[
https://issues.apache.org/jira/browse/SCB-1014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16684916#comment-16684916
]
ASF GitHub Bot commented on SCB-1014:
-------------------------------------
yhs0092 closed pull request #75: [SCB-1014] Update the description about
ExceptionToResponseConverter
URL: https://github.com/apache/servicecomb-docs/pull/75
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/java-chassis-reference/en_US/build-provider/configuration/parameter-validator.md
b/java-chassis-reference/en_US/build-provider/configuration/parameter-validator.md
index 9d13827..96abcd8 100644
---
a/java-chassis-reference/en_US/build-provider/configuration/parameter-validator.md
+++
b/java-chassis-reference/en_US/build-provider/configuration/parameter-validator.md
@@ -84,13 +84,13 @@ public class Student {
Return error can be customized with the SPI mechanism.
-* Developer can customize the returned error information by implementing the
interface ExceptionToResponseConverter, taking the
ConstraintViolationExceptionToResponseConverter as an example.
+* Developer can customize the returned error information by implementing the
interface ExceptionToProducerResponseConverter, taking the
ConstraintViolationExceptionToProducerResponseConverter as an example.
- 1. Implement the ExceptionToResponseConverter interface, override the
method, the return value of the getOrder method indicates the priority of the
validator. The smaller the value, the higher the priority.
+ 1. Implement the ExceptionToProducerResponseConverter interface, override
the method, the return value of the getOrder method indicates the priority of
the validator. The smaller the value, the higher the priority.
```java
- public class ConstraintViolationExceptionToResponseConverter
- implements ExceptionToResponseConverter<ConstraintViolationException>
{
+ public class ConstraintViolationExceptionToProducerResponseConverter
+ implements
ExceptionToProducerResponseConverter<ConstraintViolationException> {
@Override
public Class<ConstraintViolationException> getExceptionClass() {
return ConstraintViolationException.class;
@@ -108,4 +108,4 @@ public class Student {
}
```
- 2. Add a file in the services folder under META-INF, with the implemented
interface x.x.x.ExceptionToResponseConverter(with package name\) as the name,
and the implementation class
x.x.x.ConstraintViolationExceptionToResponseConverter(with package name\) as
the content.
+ 2. Add a file in the services folder under META-INF, with the implemented
interface x.x.x.ExceptionToProducerResponseConverter(with package name\) as the
name, and the implementation class
x.x.x.ConstraintViolationExceptionToProducerResponseConverter(with package
name\) as the content.
diff --git a/java-chassis-reference/en_US/general-development/error-handling.md
b/java-chassis-reference/en_US/general-development/error-handling.md
index 11737ad..614c6aa 100644
--- a/java-chassis-reference/en_US/general-development/error-handling.md
+++ b/java-chassis-reference/en_US/general-development/error-handling.md
@@ -2,29 +2,31 @@
ServiceComb has three categories of exceptions:
* User Defined Exceptions:Exceptions defined in API. These exceptions are
generated to swagger.
+
* Control Messages Exceptions:Most of them are thrown by handlers. e.g. Flow
control throws TOO_MANY_REQUESTS_STATUS.
-```
-CommonExceptionData errorData = new CommonExceptionData("rejected by qps
flowcontrol");
-asyncResp.producerFail(new
InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));
-```
+ ```java
+ CommonExceptionData errorData = new CommonExceptionData("rejected by qps
flowcontrol");
+ asyncResp.producerFail(new
InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));
+ ```
-* Unknown Exceptions:Unkown exceptions may throw by service implementation
like NullPointerException or network SocketException. These exceptions will be
caught by ServiceComb and return 490, 590 like error code. e.g.
+* Unknown Exceptions:Unkown exceptions may throw by service implementation
like NullPointerException or network SocketException. These exceptions will be
caught by ServiceComb and return 490, 590 like error code. e.g.
-```
-CommonExceptionData errorData = new CommonExceptionData(cause.getMessage());
-asyncResp.producerFail(new InvocationException(590, errorData)
-
-or
-asyncResp.consumerFail(new InvocationException(490, errorData)
-```
+ ```java
+ CommonExceptionData errorData = new CommonExceptionData(cause.getMessage());
+ asyncResp.producerFail(new InvocationException(590, errorData)
+ ```
+ or
+ ```java
+ asyncResp.consumerFail(new InvocationException(490, errorData)
+ ```
## User Defined Exceptions
-Users can use @ApiResonse to define different types of exceptions。e.g.
+Users can use @ApiResonse to define different types of exceptions. e.g.
-```
+```java
@Path("/errorCode")
@POST
@ApiResponses({
@@ -51,9 +53,9 @@ Users can use @ApiResonse to define different types of
exceptions。e.g.
}
```
-and client code know exception type.
+and client code know exception type.
-```
+```java
MultiRequest request = new MultiRequest();
request.setCode(200);
@@ -87,7 +89,7 @@ and client code know exception type.
Control message exceptions not defined in swagger and the type is unknown for
serializers. Client code use raw type to process it.
-```
+```java
JsonObject requestJson = new JsonObject();
requestJson.put("code", 400);
requestJson.put("message", "test message");
@@ -112,51 +114,57 @@ Unknown exceptions are wrapped to 490 and 590 error code,
and type is CommonExce
## Customize exceptions type
-We can define actual types for error code and convert one type of exception to
another.
+We can define actual types for error code and convert one type of exception to
another.
* define actual types for error code
-Define actual types for error code can make consumer code easier, and do not
to use raw types. Users can implement a SPI interface
org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper to
specify the target exception type for specific error code.
-```
- private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
+ Define actual types for error code can make consumer code easier, and do not
to use raw types. Users can implement a SPI interface
org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper to
specify the target exception type for specific error code.
+ ```java
+ private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
- static {
- ResponseMeta meta = new ResponseMeta();
- meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
- CODES.put(500, meta);
- }
-
- @Override
- public Map<Integer, ResponseMeta> getMapper() {
- return CODES;
- }
-```
+ static {
+ ResponseMeta meta = new ResponseMeta();
+
meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
+ CODES.put(500, meta);
+ }
-* convert one type of exception to another
+ @Override
+ public Map<Integer, ResponseMeta> getMapper() {
+ return CODES;
+ }
+ ```
-ServiceComb will serialize InvocationException data to response, and when
exception type is not InvocationException,a wrapped InvocationException with
error code 490, 590 is created。Implement SPI interface
org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
can convert from one type of exception to the other.
+* convert one type of exception to another
-```
-public class CustomExceptionToResponseConverter implements
ExceptionToResponseConverter<IllegalStateException> {
- @Override
- public Class<IllegalStateException> getExceptionClass() {
- return IllegalStateException.class;
- }
+ ServiceComb will serialize `InvocationException` data to response, and when
the exception type is not `InvocationException`, a wrapped InvocationException
with error code 490, 590 is created. Implement SPI interface
`org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter`
can convert one type of exception to another. Here is the description about
`ExceptionToProducerResponseConverter`:
+ - the method `getExceptionClass()` indicates which type of exception this
converter handles. The converter whose `getExceptionClass()` method returns
`null` will be taken as default converter.
+ - in the method `Response convert(SwaggerInvocation swaggerInvocation, T
e)`, the exception is processed and `Response` is returned. The returned
`Response` determines the status code, resposne body of the HTTP response.
+ - the method `getOrder()` determines the priority of a converter. The less
the returned value is, the higher the priority is. If the converter does not
implement this method, the default return value is `0`. For a certain type of
exception, only the converter with the highest priority will take effect.
+ - When an exception comes, the converters will be selected according to its
type. If no converter is selected, then the type of its parent class is used to
select the converter. Such process will continue until the `Throwable` type is
used to select converter. If there is still no converter for this exception,
the default converter will be selected to process this type of exception.
+
+ ```java
+ public class CustomExceptionToProducerResponseConverter implements
ExceptionToProducerResponseConverter<IllegalStateException> {
+ @Override
+ public Class<IllegalStateException> getExceptionClass() {
+ // The return value indicates that this converter handles
IllegalStateException
+ return IllegalStateException.class;
+ }
- @Override
- public int getOrder() {
- return 100;
- }
+ @Override
+ public int getOrder() {
+ // The less the returned value is, the higher the priority is
+ return 100;
+ }
- @Override
- public Response convert(SwaggerInvocation swaggerInvocation,
IllegalStateException e) {
- IllegalStateErrorData data = new IllegalStateErrorData();
- data.setId(500);
- data.setMessage(e.getMessage());
- data.setState(e.getMessage());
- InvocationException state = new
InvocationException(Status.INTERNAL_SERVER_ERROR, data);
- return Response.failResp(state);
+ @Override
+ public Response convert(SwaggerInvocation swaggerInvocation,
IllegalStateException e) {
+ // Here the exception is processed
+ IllegalStateErrorData data = new IllegalStateErrorData();
+ data.setId(500);
+ data.setMessage(e.getMessage());
+ data.setState(e.getMessage());
+ InvocationException state = new
InvocationException(Status.INTERNAL_SERVER_ERROR, data);
+ return Response.failResp(state);
+ }
}
-}
-
-```
+ ```
diff --git
a/java-chassis-reference/zh_CN/build-provider/configuration/parameter-validator.md
b/java-chassis-reference/zh_CN/build-provider/configuration/parameter-validator.md
index 0771a51..3b5f3b9 100644
---
a/java-chassis-reference/zh_CN/build-provider/configuration/parameter-validator.md
+++
b/java-chassis-reference/zh_CN/build-provider/configuration/parameter-validator.md
@@ -86,13 +86,13 @@ public class Student {
返回错误支持自定义扩展,使用SPI机制。
-*
可以通过实现接口ExceptionToResponseConverter来自定义返回的错误信息,以ConstraintViolationExceptionToResponseConverter为例。
+*
可以通过实现接口ExceptionToProducerResponseConverter来自定义返回的错误信息,以ConstraintViolationExceptionToProducerResponseConverter为例。
- 1.
实现ExceptionToResponseConverter接口,重写方法,其中getOrder方法的返回结果表示该验证器的优先级,值越小优先级越高。
+ 1.
实现ExceptionToProducerResponseConverter接口,重写方法,其中getOrder方法的返回结果表示该验证器的优先级,值越小优先级越高。
```java
- public class ConstraintViolationExceptionToResponseConverter
- implements ExceptionToResponseConverter<ConstraintViolationException>
{
+ public class ConstraintViolationExceptionToProducerResponseConverter
+ implements
ExceptionToProducerResponseConverter<ConstraintViolationException> {
@Override
public Class<ConstraintViolationException> getExceptionClass() {
return ConstraintViolationException.class;
@@ -110,7 +110,7 @@ public class Student {
}
```
- 2.
在META-INF下的services文件夹增加一个文件,以所实现接口x.x.x.ExceptionToResponseConverter\(带包名\)为名,以具体实现类x.x.x.ConstraintViolationExceptionToResponseConverter\(带包名\)为内容。
+ 2.
在META-INF下的services文件夹增加一个文件,以所实现接口x.x.x.ExceptionToProducerResponseConverter\(带包名\)为名,以具体实现类x.x.x.ConstraintViolationExceptionToProducerResponseConverter\(带包名\)为内容。
diff --git a/java-chassis-reference/zh_CN/general-development/error-handling.md
b/java-chassis-reference/zh_CN/general-development/error-handling.md
index e53b573..6bb2a74 100644
--- a/java-chassis-reference/zh_CN/general-development/error-handling.md
+++ b/java-chassis-reference/zh_CN/general-development/error-handling.md
@@ -2,29 +2,31 @@
ServiceComb异常情况可以分为三类:
* 业务定义异常:这类异常由业务接口定义。用户在获取到服务swagger定义到时候,就能够从定义中看到这类异常对应的错误码,以及返回值类型。
+
* 处理控制异常:这类异常通常是框架处理流程上的异常。比如流控Handler抛出TOO_MANY_REQUESTS_STATUS异常。
-```
-CommonExceptionData errorData = new CommonExceptionData("rejected by qps
flowcontrol");
-asyncResp.producerFail(new
InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));
-```
+ ```java
+ CommonExceptionData errorData = new CommonExceptionData("rejected by qps
flowcontrol");
+ asyncResp.producerFail(new
InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));
+ ```
*
未知异常:这类异常发生的情况不确定。比如业务代码实现的时候,抛出NullPointerException等未捕获异常、底层的网络连接超时异常等。这类异常会由ServiceComb封装成590或者490错误返回。比如:
-```
-CommonExceptionData errorData = new CommonExceptionData(cause.getMessage());
-asyncResp.producerFail(new InvocationException(590, errorData)
-
-或者
-asyncResp.consumerFail(new InvocationException(490, errorData)
-```
+ ```java
+ CommonExceptionData errorData = new CommonExceptionData(cause.getMessage());
+ asyncResp.producerFail(new InvocationException(590, errorData)
+ ```
+ 或者
+ ```java
+ asyncResp.consumerFail(new InvocationException(490, errorData)
+ ```
## 业务定义异常
通常业务在开发服务代码的时候,只有一个返回值,但有些情况,也需要视具体情况返回不同的消息。可以通过@ApiResonse来定义不同错误码对应的返回消息。业务异常具备确定的数据类型,并且会在swagger里面体现,客户端代码在处理异常的时候,能够直接获取到错误类型。比如下面的代码:
-```
+```java
@Path("/errorCode")
@POST
@ApiResponses({
@@ -53,7 +55,7 @@ asyncResp.consumerFail(new InvocationException(490, errorData)
客户端代码可以按照如下方式处理异常。异常的类型是确定的,可以通过cast获取到异常类型。
-```
+```java
MultiRequest request = new MultiRequest();
request.setCode(200);
@@ -87,7 +89,7 @@ asyncResp.consumerFail(new InvocationException(490, errorData)
控制异常一般在接口定义里面没有声明。客户端在做异常处理的时候,不知道异常类型。可以采用弱类型的方式处理异常:
-```
+```java
JsonObject requestJson = new JsonObject();
requestJson.put("code", 400);
requestJson.put("message", "test message");
@@ -116,48 +118,54 @@ asyncResp.consumerFail(new InvocationException(490,
errorData)
* 控制消息消息体序列化
-控制消息消息体序列化的目的是简化消费者的异常处理逻辑,不用使用弱类型,而是使用确切类型。可以采用注册全局的错误码类型。
-业务需要通过SPI实现org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper接口。接口的核心内容是为每个错误码制定序列化类型:
-```
- private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
+ 控制消息消息体序列化的目的是简化消费者的异常处理逻辑,不用使用弱类型,而是使用确切类型。可以采用注册全局的错误码类型。
+
业务需要通过SPI实现org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper接口。接口的核心内容是为每个错误码制定序列化类型:
+ ```java
+ private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
- static {
- ResponseMeta meta = new ResponseMeta();
- meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
- CODES.put(500, meta);
- }
-
- @Override
- public Map<Integer, ResponseMeta> getMapper() {
- return CODES;
- }
-```
+ static {
+ ResponseMeta meta = new ResponseMeta();
+
meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
+ CODES.put(500, meta);
+ }
-* 异常转换
+ @Override
+ public Map<Integer, ResponseMeta> getMapper() {
+ return CODES;
+ }
+ ```
-如果业务不对异常进行转换,ServiceComb会将InvocationException中的data直接序列化到响应消息中。如果不是InvocationException,则转换为490,
590,序列化的消息为CommonExceptionData。业务可以通过SPI实现org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter对异常进行转换。该接口的核心是需要指定转换的类型,以及转换处理逻辑。
+* 异常转换
-```
-public class CustomExceptionToResponseConverter implements
ExceptionToResponseConverter<IllegalStateException> {
- @Override
- public Class<IllegalStateException> getExceptionClass() {
- return IllegalStateException.class;
- }
+
如果业务不对异常进行转换,ServiceComb会将InvocationException中的data直接序列化到响应消息中。如果不是InvocationException,则转换为490,
590,序列化的消息为CommonExceptionData。业务可以通过SPI实现`org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter`对异常进行转换。`ExceptionToProducerResponseConverter`的说明如下:
+ -
`getExceptionClass()`方法会返回converter实现类所处理的异常类型。如果该方法返回`null`,则说明此实现类为默认converter。
+ - `Response convert(SwaggerInvocation swaggerInvocation, T
e)`方法中实现处理异常的逻辑,该方法返回的`Response`决定了ServiceComb将会返回何种状态码、何种response body的应答。
+ -
`getOrder()`方法用以确定converter实现类的优先级,该方法返回的值越小,优先级越高,如果不覆写该方法的话,则返回默认优先级`0`。对于处理同一异常类型的converter(或默认converter),只有优先级最高的生效。
+ -
在为异常选择converter时,会从异常本身的类型开始匹配,如果找不到对应的converter则逐级向上查找父类型的converter。当匹配到`Throwable`仍未找到converter时,将使用默认converter处理异常。
+
+ ```java
+ public class CustomExceptionToProducerResponseConverter implements
ExceptionToProducerResponseConverter<IllegalStateException> {
+ @Override
+ public Class<IllegalStateException> getExceptionClass() {
+ // 返回IllegalStateException表示该converter处理IllegalStateException类型的异常
+ return IllegalStateException.class;
+ }
- @Override
- public int getOrder() {
- return 100;
- }
+ @Override
+ public int getOrder() {
+ // 返回的order值越小,优先级越高
+ return 100;
+ }
- @Override
- public Response convert(SwaggerInvocation swaggerInvocation,
IllegalStateException e) {
- IllegalStateErrorData data = new IllegalStateErrorData();
- data.setId(500);
- data.setMessage(e.getMessage());
- data.setState(e.getMessage());
- InvocationException state = new
InvocationException(Status.INTERNAL_SERVER_ERROR, data);
- return Response.failResp(state);
+ @Override
+ public Response convert(SwaggerInvocation swaggerInvocation,
IllegalStateException e) {
+ // 这里是处理异常的逻辑
+ IllegalStateErrorData data = new IllegalStateErrorData();
+ data.setId(500);
+ data.setMessage(e.getMessage());
+ data.setState(e.getMessage());
+ InvocationException state = new
InvocationException(Status.INTERNAL_SERVER_ERROR, data);
+ return Response.failResp(state);
+ }
}
-}
-
-```
+ ```
----------------------------------------------------------------
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:
[email protected]
> Fix priority problem of ExceptionToResponseConverter
> ----------------------------------------------------
>
> Key: SCB-1014
> URL: https://issues.apache.org/jira/browse/SCB-1014
> Project: Apache ServiceComb
> Issue Type: Bug
> Reporter: YaoHaishi
> Assignee: YaoHaishi
> Priority: Major
>
> Currently the priority rule of default ExceptionToResponseConverter is that
> the smaller the order is, the higher the priority is. But the other common
> ExceptionToResponseConverters obey the contrary priority rule.
> We need to modify the implementation logic of ExceptionToResponseConverters
> to make sure the two kinds of ExceptionToResponseConverters obey the same
> priority rule.
> And the name of ExceptionToResponseConverter will be changed to remind users
> to be aware of the modification.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)