Spring Retry @Recover方法抛出的自定义异常被封装为UndeclaredThrowableException的问题
Spring Retry @Recover方法抛出的自定义异常被封装为UndeclaredThrowableException的问题
嘿,我来帮你搞定这个问题!你遇到的UndeclaredThrowableException包装异常的情况,核心原因其实很明确,咱们一步步来分析和解决:
核心问题:@Recover方法的访问修饰符不对
你当前的@Recover方法用了private修饰符,这可是Spring Retry的大忌!Spring Retry是通过动态代理机制来调用恢复方法的,private方法无法被代理类访问,底层就会把你实际抛出的SearchException封装成UndeclaredThrowableException抛出来,这就是你看到的现象。
解决方案步骤
1. 把@Recover方法改成public
直接调整方法的访问修饰符,让代理类能正常调用它:
// 修改后的@Recover方法,访问修饰符改为public @Recover public SearchResponseMapObject recover(SearchException e, String username) throws SearchException { try { searchService = searchServiceFactory.getSecondary(); HashMap<String, Object> responseMap = searchService.getResponse(username); //throws NotFoundInSecondaryException SearchResponseMapObject secondaryResponseMapObject = processResponseMap(responseMap); return secondaryResponseMapObject; } catch (SearchException ex) { throw ex; } }
2. 确保主重试方法的异常声明匹配
你的主重试方法(就是标注了@Retryable的那个方法)需要明确声明抛出SearchException(或者它的父类),这样Spring Retry才能正确关联到对应的@Recover方法,避免异常被额外封装。比如主方法应该类似这样:
@Retryable(value = {NotFoundInPrimaryException.class}) public SearchResponseMapObject primarySearch(String username) throws SearchException { // 你的主数据源查询逻辑,会抛出NotFoundInPrimaryException }
3. 确认自定义异常的继承关系
要保证NotFoundInSecondaryException是SearchException的子类,这样在catch块里抛出的异常才能被@Recover方法的throws SearchException声明覆盖,不会出现类型不匹配的问题。
做完这几步,你再测试一下,应该就能直接捕获到你自定义的SearchException,而不是被包装后的UndeclaredThrowableException了。
备注:内容来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

