EarthChen commented on issue #8363:
URL: https://github.com/apache/dubbo/issues/8363#issuecomment-897639172


   > Scenario1 : Non-Protobuf
   > Exception will be serialized and rethrowed at client side.
   > Scenario2 : Protobuf
   > Serialization of origin exception is not supported, insteadly a 
`TripleRpcException` will be returned. Users can return and get custom error 
code in response's attachments like this
   > 
   > ```java
   > @Activate(group = {CommonConstants.CONSUMER})
   > public class BizErrorCodeClientFilter implements ClusterFilter, 
BaseFilter.Listener {
   >     @Override
   >     public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
   >         return invoker.invoke(invocation);
   >     }
   > 
   >     @Override
   >     public void onResponse(Result appResponse, Invoker<?> invoker, 
Invocation invocation) {
   >         appResponse.getObjectAttachment("biz-err-code");
   >     }
   > 
   >     @Override
   >     public void onError(Throwable t, Invoker<?> invoker, Invocation 
invocation) {
   >     }
   > }
   > ```
   
   # follow Scenario2 ,this is  more detailed demo 
   
   # provider
   
   ## biz code
   
   ```java
   @DubboService
   @Slf4j
   public class MyServiceImpl implements MyService {
   
       @Override
       public HelloReply sayHello(HelloRequest helloRequest) {
           log.error("test runtimeException helloRequest={}", helloRequest);
           throw new DubboBizException(1111, "test");
       }
   
       @Override
       public CompletableFuture<HelloReply> sayHelloAsync(HelloRequest 
helloRequest) {
           return null;
       }
   
   }
   ```
   
   ## filter
   
   copy `org.apache.dubbo.rpc.filter.ExceptionFilter` and add yours biz 
exception logic
   
   ```java
   @Activate(group = CommonConstants.PROVIDER)
   public class DubboProviderExceptionFilter implements Filter, Filter.Listener 
{
   
       private static Logger log = 
LoggerFactory.getLogger(DubboProviderExceptionFilter2.class);
   
   
       @Override
       public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
           return invoker.invoke(invocation);
       }
   
       @Override
       public void onResponse(Result appResponse, Invoker<?> invoker, 
Invocation invocation) {
           if (appResponse.hasException() && GenericService.class != 
invoker.getInterface()) {
               try {
                   Throwable exception = appResponse.getException();
   
                   //。。。。
   
                   // user-defined biz exception
                   if (exception instanceof DubboBizException) {
                       DubboBizException bizException = (DubboBizException) 
exception;
                       Map<String, String> attach = 
appResponse.getAttachments();
                       attach.put(DubboConstant.CODE, 
bizException.getCode().toString());
                       attach.put(DubboConstant.MSG, bizException.getMessage());
                       return;
                   }
   
                   //。。。。
                   // directly throw if it's dubbo exception
                   if (exception instanceof RpcException) {
                       return;
                   }
   
                   // otherwise, wrap with RuntimeException and throw back to 
the client
                   appResponse.setException(new 
RuntimeException(StringUtils.toString(exception)));
               } catch (Throwable e) {
                   log.warn("Fail to ExceptionFilter when called by " + 
RpcContext.getServiceContext().getRemoteHost() + ". service: " + 
invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + 
", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
               }
           }
       }
   
       @Override
       public void onError(Throwable e, Invoker<?> invoker, Invocation 
invocation) {
           log.error("Got unchecked and undeclared exception which called by " 
+ RpcContext.getServiceContext().getRemoteHost() + ". service: " + 
invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + 
", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
       }
   }
   ```
   
   # Consumer
   
   ## filter
   
   ```java
   @Activate(group = {CommonConstants.CONSUMER})
   public class DubboConsumerClusterExceptionFilter implements ClusterFilter, 
ClusterFilter.Listener {
       private static Logger log = 
LoggerFactory.getLogger(DubboConsumerClusterExceptionFilter.class);
       @Override
       public void onResponse(Result appResponse, Invoker<?> invoker, 
Invocation invocation) {
           Map<String, String> attach = appResponse.getAttachments();
           String code = attach.get(DubboConstant.CODE);
           String msg = attach.get(DubboConstant.MSG);
           if (!StringUtils.isBlank(code)) {
               appResponse.setException(new 
DubboBizException(Integer.parseInt(code), msg));
           }
       }
   
       @Override
       public void onError(Throwable e, Invoker<?> invoker, Invocation 
invocation) {
           log.error("Got unchecked and undeclared exception which called by " 
+ RpcContext.getServiceContext().getRemoteHost() + ". service: " + 
invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + 
", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
       }
   
       @Override
       public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
           return invoker.invoke(invocation);
       }
   }
   ```
   
   ## result
   
   
![image](https://user-images.githubusercontent.com/20179425/129204617-62326d9f-1cd3-4ed8-84d5-8f8c7091282e.png)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to