yhs0092 commented on a change in pull request #702: [SCB-580] fix response of the upload file too large URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/702#discussion_r188506146
########## File path: transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java ########## @@ -64,9 +69,85 @@ private void failureHandler(RoutingContext context) { e = cause; } } - restProducerInvocation.sendFailResponse(e); - // 走到这里,应该都是不可控制的异常,直接关闭连接 + // only when unexpected exception happens, it will run into here. + // the connection should be closed. + handleFailureAndClose(context, restProducerInvocation, e); + } + + /** + * Try to find out the failure information and send it in response. + */ + private void handleFailureAndClose(RoutingContext context, AbstractRestInvocation restProducerInvocation, + Throwable e) { + if (null != restProducerInvocation) { + // if there is restProducerInvocation, let it send exception in response. The exception is allowed to be null. + sendFailResponseByInvocation(context, restProducerInvocation, e); + return; + } + + if (null != e) { + // if there exists exception, try to send this exception by RoutingContext + sendExceptionByRoutingContext(context, e); + return; + } + + // if there is no exception, the response is determined by status code. + sendFailureRespDeterminedByStatus(context); + } + + /** + * Try to determine response by status code, and send response. + */ + private void sendFailureRespDeterminedByStatus(RoutingContext context) { + Family statusFamily = Family.familyOf(context.statusCode()); + if (Family.CLIENT_ERROR.equals(statusFamily) || Family.SERVER_ERROR.equals(statusFamily) || Family.OTHER + .equals(statusFamily)) { + context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD) + .setStatusCode(context.statusCode()).end(); + } else { + // it seems the status code is not set properly + context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD) + .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode()) + .setStatusMessage(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()) + .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())); + } + context.response().close(); + } + + /** + * Use routingContext to send failure information in throwable. + */ + private void sendExceptionByRoutingContext(RoutingContext context, Throwable e) { + if (InvocationException.class.isInstance(e)) { + InvocationException invocationException = (InvocationException) e; + context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD) Review comment: I choose this content type to avoid body decode problem. If user set provider's operation produce "text/plain", and we set the Content-Type header as "application/json", it will cause consumer failed to decode response body, and the consumer will response like below: ```json { "message": "method POST, path /upload/multipartFileUpload/, statusCode 413, reasonPhrase Request Entity Too Large, response content-type application/json is not supported" } ``` But "*/*" will let the producer use the default ProduceProcessor to decode the body. No matter it's json processor or text processor, it will handle the body without exception thrown. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services