You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 12:59:33