一、现象描述
项目启动成功,但是在使用某项功能的时候,provider抛出BusinessException异常,网关或者consumer中获取到的Exception不是BusinessException对象,导致底层的异常信息无法正常被上层获取;参见下图
1. provider
2. gateway网关层
在上面的问题中,如果provider中校验失败,抛出了BusinessException;在网关层中,获取到的异常不是上面的BusinessException,而是下面的Exception(如果有RuntimeException,则会选择RuntimeException)
二、原因说明
Dubbo中自定义了异常处理机制,主要是通过ExceptionFilter类做了相关处理,对我们手动抛出的自定义异常做了相关封装
ExceptionFilter.handler中的处理过程
- 如果是checked异常,直接抛出
- 在方法签名上有声明,直接抛出
- 异常类和接口类在同一jar包里,直接抛出
- 是JDK自带的异常,直接抛出
- 是Dubbo本身的异常,直接抛出
- 否则,包装成RuntimeException抛给客户端
由此可见,上述中的异常会被包装成RuntimeException;
三、解决方案
-
在dubbo层的接口方法抛出相关异常(使用该方法,需要自定义异常类具备无参构造方法)
-
BusinessException继承dubbo中的RpcException
-
异常类和dubbo接口放在同一个jar包中
四、补充说明
dubbo官方钉钉群:21973601