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>