Skip to content

Commit

Permalink
Refine http exception process (#14472)
Browse files Browse the repository at this point in the history
  • Loading branch information
oxsean authored Jul 29, 2024
1 parent e9d829c commit 9a1e479
Show file tree
Hide file tree
Showing 30 changed files with 421 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ public void mergeProtocol(ProtocolConfig sourceConfig) {
if (sourceConfig == null) {
return;
}
Field[] targetFields = this.getClass().getDeclaredFields();
Field[] targetFields = getClass().getDeclaredFields();
try {
Map<String, Object> protocolConfigMap = CollectionUtils.objToMap(sourceConfig);
for (Field targetField : targetFields) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ public class TripleConfig implements Serializable {

private static final long serialVersionUID = -3682252713701362155L;

/**
* Whether enable verbose mode.
* When true, the application will produce detailed logging output
* to help with debugging and monitoring. This is useful for
* troubleshooting and understanding the application's behavior in detail.
* <p>The default value is false.
*/
private Boolean verbose;

/**
* Maximum allowed size for HTTP request bodies.
* Limits the size of request to prevent excessively large request.
Expand Down Expand Up @@ -122,6 +131,14 @@ public class TripleConfig implements Serializable {
@Nested
private ServletConfig servlet;

public Boolean getVerbose() {
return verbose;
}

public void setVerbose(Boolean verbose) {
this.verbose = verbose;
}

public Integer getMaxBodySize() {
return maxBodySize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ public static void validateProtocolConfig(ProtocolConfig config) {
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
checkExtension(config.getScopeModel(), Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
checkExtension(config.getScopeModel(), Dispatcher.class, "dispather", config.getDispather());
checkExtension(config.getScopeModel(), Dispatcher.class, "dispather", config.getDispatcher());
checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void dispatcher() {
void dispather() {
ProtocolBuilder builder = new ProtocolBuilder();
builder.dispather("mockdispatcher");
Assertions.assertEquals("mockdispatcher", builder.build().getDispather());
Assertions.assertEquals("mockdispatcher", builder.build().getDispatcher());
}

@Test
Expand Down
3 changes: 3 additions & 0 deletions dubbo-distribution/dubbo-all-shaded/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,9 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.tri.stream.ClientStreamFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.ExceptionHandler</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory</resource>
</transformer>
Expand Down
3 changes: 3 additions & 0 deletions dubbo-distribution/dubbo-all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.tri.stream.ClientStreamFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.ExceptionHandler</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory</resource>
</transformer>
Expand Down
3 changes: 3 additions & 0 deletions dubbo-distribution/dubbo-core-spi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.tri.stream.ClientStreamFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.ExceptionHandler</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory</resource>
</transformer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.apache.dubbo.remoting.http12;

import org.apache.dubbo.remoting.http12.exception.EncodeException;
import org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException;
import org.apache.dubbo.remoting.http12.exception.HttpStatusException;
import org.apache.dubbo.remoting.http12.message.HttpMessageEncoder;

Expand All @@ -31,6 +30,8 @@ public abstract class AbstractServerHttpChannelObserver implements CustomizableH

private ErrorResponseCustomizer errorResponseCustomizer = ErrorResponseCustomizer.NO_OP;

private ExceptionHandler<Throwable, ?> exceptionHandler;

private HttpMessageEncoder responseEncoder;

private String altSvc;
Expand Down Expand Up @@ -65,6 +66,12 @@ public void setErrorResponseCustomizer(ErrorResponseCustomizer errorResponseCust
this.errorResponseCustomizer = errorResponseCustomizer;
}

@Override
@SuppressWarnings("unchecked")
public void setExceptionHandler(ExceptionHandler<?, ?> exceptionHandler) {
this.exceptionHandler = (ExceptionHandler<Throwable, ?>) exceptionHandler;
}

public void setAltSvc(String altSvc) {
this.altSvc = altSvc;
}
Expand Down Expand Up @@ -101,11 +108,16 @@ public final void onError(Throwable throwable) {
if (closed) {
return;
}
if (throwable instanceof HttpResultPayloadException) {
onNext(((HttpResultPayloadException) throwable).getResult());
onCompleted(null);
return;

if (exceptionHandler != null) {
HttpResult<?> result = exceptionHandler.handle(throwable);
if (result != null) {
onNext(result);
onCompleted(null);
return;
}
}

try {
doOnError(throwable);
} catch (Throwable ex) {
Expand Down Expand Up @@ -184,14 +196,23 @@ protected final String resolveStatusCode(Throwable throwable) {
protected final ErrorResponse buildErrorResponse(String statusCode, Throwable throwable) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setStatus(statusCode);
errorResponse.setMessage(throwable.getMessage());
if (throwable instanceof HttpStatusException) {
errorResponse.setMessage(throwable.getMessage());
} else {
errorResponse.setMessage("Internal Server Error");
}
errorResponseCustomizer.accept(errorResponse, throwable);
return errorResponse;
}

protected final HttpOutputMessage buildMessage(Object data) throws Throwable {
if (data instanceof HttpResult) {
data = ((HttpResult<?>) data).getBody();
HttpResult<?> result = (HttpResult<?>) data;
data = result.getBody();
if (data instanceof Throwable) {
String statusCode = String.valueOf(result.getStatus());
data = buildErrorResponse(statusCode, (Throwable) data);
}
}
HttpOutputMessage outputMessage = encodeHttpOutputMessage(data);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ public interface CustomizableHttpChannelObserver<T> extends HttpChannelObserver<
void setTrailersCustomizer(TrailersCustomizer trailersCustomizer);

void setErrorResponseCustomizer(ErrorResponseCustomizer errorResponseCustomizer);

void setExceptionHandler(ExceptionHandler<?, ?> exceptionHandler);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.remoting.http12;

import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;

@SPI(scope = ExtensionScope.FRAMEWORK)
public interface ExceptionHandler<E extends Throwable, T> {

HttpResult<T> handle(E error);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public enum HttpHeaderNames {

TRANSFER_ENCODING("transfer-encoding"),

LOCATION("location"),

TE("te"),

ALT_SVC("alt-svc"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,16 @@ static <T> Builder<T> builder() {
return new Builder<>();
}

static <T> Builder<T> builder(T body) {
return new Builder<T>().body(body);
static <T> HttpResult<T> of(T body) {
return new Builder<T>().body(body).build();
}

static <T> HttpResult<T> of(int status, T body) {
return new Builder<T>().status(status).body(body).build();
}

static <T> HttpResult<T> of(HttpStatus status, T body) {
return new Builder<T>().status(status).body(body).build();
}

static <T> HttpResult<T> status(int status) {
Expand All @@ -49,6 +57,10 @@ static <T> HttpResult<T> ok() {
return new Builder<T>().status(HttpStatus.OK).build();
}

static <T> HttpResult<T> moved(String url) {
return new Builder<T>().moved(url).build();
}

static <T> HttpResult<T> found(String url) {
return new Builder<T>().found(url).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ public enum HttpStatus {
CREATED(201),
ACCEPTED(202),
NO_CONTENT(204),
MOVED_PERMANENTLY(301),
FOUND(302),
BAD_REQUEST(400),
UNAUTHORIZED(401),
FORBIDDEN(403),
NOT_FOUND(404),
METHOD_NOT_ALLOWED(405),
PRECONDITION_FAILED(412),
REQUEST_TIMEOUT(408),
CONFLICT(409),
UNSUPPORTED_MEDIA_TYPE(415),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ public HttpResultPayloadException(HttpResult<?> result) {

public HttpResultPayloadException(int statusCode, Object body) {
super(statusCode);
result = HttpResult.builder(body).status(statusCode).build();
result = HttpResult.of(statusCode, body);
}

public HttpResultPayloadException(Object body) {
super(HttpStatus.OK.getCode());
result = HttpResult.builder(body).ok().build();
this(HttpStatus.OK.getCode(), body);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public void setOutputStream(OutputStream os) {
public void sendRedirect(String location) {
check();
setStatus(HttpStatus.FOUND.getCode());
setHeader("location", location);
setHeader(HttpHeaderNames.LOCATION.getName(), location);
commit();
}

Expand Down Expand Up @@ -354,7 +354,7 @@ public HttpResult<Object> toHttpResult() {
if (body == null) {
body = outputStream;
}
return HttpResult.builder(body).status(status).headers(headers).build();
return HttpResult.builder().status(status).body(body).headers(headers).build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.dubbo.remoting.http12.message;

import org.apache.dubbo.common.utils.DateUtils;
import org.apache.dubbo.remoting.http12.HttpHeaderNames;
import org.apache.dubbo.remoting.http12.HttpResult;
import org.apache.dubbo.remoting.http12.HttpStatus;

Expand Down Expand Up @@ -85,8 +86,12 @@ public Builder<T> ok() {
return status(HttpStatus.OK.getCode());
}

public Builder<T> moved(String url) {
return status(HttpStatus.MOVED_PERMANENTLY).header(HttpHeaderNames.LOCATION.getName(), url);
}

public Builder<T> found(String url) {
return status(HttpStatus.FOUND).header("location", url);
return status(HttpStatus.FOUND).header(HttpHeaderNames.LOCATION.getName(), url);
}

public Builder<T> error() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ public interface Constants {
String H2_SETTINGS_BUILTIN_SERVICE_INIT = "dubbo.tri.builtin.service.init";
String H2_SETTINGS_PASS_THROUGH_STANDARD_HTTP_HEADERS = "dubbo.rpc.tri.pass-through-standard-http-headers";

String H3_SETTINGS_HTTP3_ENABLE = "dubbo.protocol.triple.http3.enable";
String H3_SETTINGS_SERVLET_ENABLE = "dubbo.protocol.triple.servlet.enable";
String H2_SETTINGS_VERBOSE_ENABLED = "dubbo.protocol.triple.verbose";
String H2_SETTINGS_SERVLET_ENABLED = "dubbo.protocol.triple.servlet.enabled";
String H3_SETTINGS_HTTP3_ENABLED = "dubbo.protocol.triple.http3.enabled";

String ADAPTIVE_LOADBALANCE_ATTACHMENT_KEY = "lb_adaptive";
String ADAPTIVE_LOADBALANCE_START_TIME = "adaptive_startTime";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,42 @@ public static Code httpStatusToGrpcCode(int httpStatusCode) {
}
}

public static int grpcCodeToHttpStatus(Code code) {
switch (code) {
case OK:
return HttpResponseStatus.OK.code();
case CANCELLED:
return 499;
case UNKNOWN:
case DATA_LOSS:
case INTERNAL:
return HttpResponseStatus.INTERNAL_SERVER_ERROR.code();
case INVALID_ARGUMENT:
case FAILED_PRECONDITION:
case OUT_OF_RANGE:
return HttpResponseStatus.BAD_REQUEST.code();
case DEADLINE_EXCEEDED:
return HttpResponseStatus.GATEWAY_TIMEOUT.code();
case NOT_FOUND:
return HttpResponseStatus.NOT_FOUND.code();
case ALREADY_EXISTS:
case ABORTED:
return HttpResponseStatus.CONFLICT.code();
case PERMISSION_DENIED:
return HttpResponseStatus.FORBIDDEN.code();
case RESOURCE_EXHAUSTED:
return HttpResponseStatus.TOO_MANY_REQUESTS.code();
case UNIMPLEMENTED:
return HttpResponseStatus.NOT_IMPLEMENTED.code();
case UNAVAILABLE:
return HttpResponseStatus.SERVICE_UNAVAILABLE.code();
case UNAUTHENTICATED:
return HttpResponseStatus.UNAUTHORIZED.code();
default:
return -1;
}
}

public boolean isOk() {
return Code.isOk(code.code);
}
Expand Down
Loading

0 comments on commit 9a1e479

Please sign in to comment.