API 接口中抛出的异常类型,有一系列的规则,代码在 ExceptionFilter
的 onResponse
中。
1. 如果是受检异常(非Runtime
)就直接抛出
这是因为如果是受检异常,接口定义的 throws
中需要涵盖,调用端需要捕获该异常,该异常一定能访问到。
2. RuntimeException 并且接口 throws 时
这种情况下,接口指明抛出的异常,调用端也能获取该异常,因此可以直接抛出。
3. 异常和接口在一个 jar 包时
此时也可以直接抛出。
4. java.
和 javax.
前缀的异常时
这些都是 JDK 自带的,可以直接抛出。
5. dubbo RpcException 及其子类时
调用方也集成了 dubbo,因此可以直接抛出。
6. 其他情况
如果不满足前 5 个规则,就会被包装成统一的异常,导致异常信息变得冗长模糊。
7. 问题
dubbo 上述逻辑只在 A 调用 B 这种简单调用时有效,如果出现了 A->B->C,当 C 抛出异常时,B 能够正常接收,如果是 Runtime
类型的,B 没有处理时,会直接抛给 A,但是此时 B 抛出的异常和 B 接口没有任何关系,这就导致 B 在过滤器中进入第 6 种情况,导致 A 接收到的异常变得模糊。
如果系统基础包中定义了统一的异常类,在跨多次服务调用时仍然无法使用,想要避免问题只能从前 6 条规则入手。