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

WebClient onStatus方法抛出的自定义异常无法被对应catch块捕获

问题根因

自定义异常无法被精准捕获,核心是3个问题:

  • Reactor响应式异常包装机制:WebClient底层基于Reactor实现,如果你定义的AuthException是受检异常(直接继承Exception而非RuntimeException),通过Mono.error()抛出时会被Reactor自动包装为运行时异常抛出,外层catch匹配不到原生AuthException类型。
  • 调用链路写错:你贴的getResponse方法try块中调用的是randomService.getResponse(request),根本没有调用包含WebClient逻辑的returnResponse方法,异常不会进入当前try-catch链路。
  • 代码笔误导致分支不触发:onStatus里的401判断写的是if(401)属于无效判断,永远不会进入抛AuthException的分支;另外还有BodyInserters.formatValue不存在、new AuthException("traceid)字符串未闭合的语法错误。
排查方向
  • 检查AuthException的继承关系,确认是否为受检异常
  • 梳理调用链路,确认外层try块实际调用了WebClient请求方法
  • 在通用Exception捕获分支打印异常栈和e.getCause(),确认是否存在被包装的AuthException
  • 校验onStatus中的状态码判断逻辑,确认401场景确实能走到抛自定义异常的分支
正确实现
  1. 调整自定义异常为运行时异常,避免被Reactor自动包装
public class AuthException extends RuntimeException {
    public AuthException(String message) {
        super(message);
    }
}
  1. 修正WebClient请求逻辑,补全正确判断,增加异常解包处理
public String returnResponse(String request){
    return webclient.post()
            .uri("目标接口地址")
            .header("头名称","头值")
            .body(BodyInserters.fromValue(request))
            .retrieve()
            .onStatus(HttpStatus::is4xxClientError, clientRes -> {
                // 正确判断401状态码
                if(clientRes.statusCode().equals(HttpStatus.UNAUTHORIZED)){
                    return Mono.error(new AuthException("traceid"));
                }
                return Mono.error(new InternalServerError("客户端请求异常"));
            })
            .bodyToMono(String.class)
            // 异常解包,避免被Reactor包装后类型不匹配
            .onErrorMap(e -> e.getCause() instanceof AuthException ? e.getCause() : e)
            .block();
}
  1. 修正外层调用逻辑,补全兜底的异常类型判断
public String getResponse(String request){ 
    try{
        // 调用正确的WebClient请求方法
        return returnResponse(request);
    }catch(AuthException e){
        throw new AuthException(e.getMessage());
    }catch(Exception e){
        // 兜底处理可能存在的包装异常
        if(e.getCause() instanceof AuthException authEx){
            throw authEx;
        }
        throw new InternalServerError(e.getMessage());
    }
}

补充说明:如果因为业务约束不能把AuthException改成运行时异常,保留上述代码中的onErrorMap解包和catch块的cause判断逻辑,也可以实现自定义异常的精准捕获。

内容的提问来源于stack exchange,提问作者Esh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:06:19