1.问题
项目中部分模块单独部署,模块间服务调用使用dubbo,当服务提供者抛出了自定义的异常时,服务消费者捕获的是一个RuntimeException而不是自定义的异常,导致获取自定义异常的message时,得到的不仅仅是抛出的message,而是一个异常栈。
2.原因
dubbo服务提供者抛出的异常会被 com.alibaba.dubbo.rpc.filter.ExceptionFilter拦截处理,若是自定义的异常,会被包装成RuntimeException抛给服务消费者。
ExceptionFilter处理逻辑:
(1)服务提供者实现了GenericService接口,直接抛出;
(2)如果是checked异常,直接抛出;
(3)在方法签名上有声明,直接抛出;
(4)异常类和接口类在同一jar包里,直接抛出;
(5)是JDK自带的异常,直接抛出;
(6)是Dubbo本身的异常,直接抛出;
(7)否则,包装成RuntimeException抛给客户端。
具体参见“https://blog.csdn.net/mj158518/article/details/51228649”,非常详细。
3.解决方式(针对ExceptionFilter的处理机制,使其满足抛出条件)
(1)服务提供者实现GenericService接口;
(2)使用checked异常;
(3)服务提供者的api方法上直接throws自定义异常;
(4)自定义异常类放在服务提供者的jar包里;
(5)实现dubbo的filter,自定义provider的异常处理逻辑;
(6)网上还看见直接修改dubbo的ExceptionFilter源码,将自定义异常加入抛出支持后重新打成jar包。