Dubbo Provider返回异常,可查看 ExceptionFilter.onSuccess方法,逻辑就不说了,说结论:
- 如果接口继承了GenericService,直接放回异常(没试过)
- 如果返回的 是Exception,且不是RumTimeException,直接返回异常(可以理解为检查异常吗~~~)
- 如果是该异常在接口上异常抛出的类型,直接返回异常
- 异常类和接口类,放在一个jar里
- 如果异常包名 以 java.或者javax.开头,直接返回(可以理解为jdk自带的吗~~~)
- 如果是RpcException,直接返回
- 其他,返回 new RunTimeException(StringUtils.toString(exception))
但是,Spring那边抛出的异常出现了 UndeclaredThrowableException、InvocationTargetException
这就涉及到java基础部分
首先反射部分,通过Method.invoke调用方法时,被调用方法出现里异常,则会抛出 InvocationTargetException
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, nvocationTargetException
再之后是动态代理的异常,jdk动态代理生成代码张这样
public final void test() throws BaseException {//BaseException为自定义异常 try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } }
由上图可知,当被代理的方法调用,抛出了非 RuntimeException或者Error时,便抛出UndeclaredThrowableException
解决Dubbo自定义异常方案:
1、UndeclaredThrowableException.getUndeclaredThrowable()获取InvocationTargetException,
InvocationTargetException.getTargetException()便可获取实际对象
2、将异常类和接口放在一起
3、自定义实现ExceptionFilter:
<dubbo:provider filter="customExceptionFilter,-exception" ></dubbo:provider>