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

Spring WebFlux WebClient无法捕获异常问题求助

问题排查与解决方案

核心问题原因

  1. 响应式异步特性导致try-catch失效:try-catch只能捕获当前线程同步执行的异常,而WebClient的响应式操作(Mono)是延迟异步执行的,只有调用subscribe()后才会真正发起请求,错误会在异步线程中抛出,根本不会进入外层的try-catch块。
  2. 未正确处理订阅阶段的错误:你虽然用onErrorResume把原始连接异常转换成了自定义CantValidateTokenException,但订阅时只提供了成功回调,没有错误回调,导致异常被Reactor包装成ErrorCallbackNotImplemented抛出,无法被你预期的逻辑捕获。

解决方案

场景1:普通服务调用场景

在subscribe()时添加错误回调,直接处理自定义异常:

Mono<String> result = webClient.get()
        .uri(uriBuilder -> uriBuilder.path("/users/validate")
                .queryParam("token", authHeaderSearch)
                .build())
        .retrieve()
        .bodyToMono(String.class)
        .onErrorResume(Exception.class, throwable -> Mono.error(new CantValidateTokenException("连接验证服务失败")));

// 订阅时同时处理成功和错误逻辑
result.subscribe(
        e -> log.info("Token check result is: " + e),
        error -> {
            // 在这里处理自定义异常
            if (error instanceof CantValidateTokenException) {
                // 你的业务处理逻辑
                log.error("令牌验证失败", error);
            }
        }
);

场景2:WebFilter/Gateway过滤器场景(你的代码是AuthFilter)

网关过滤器需要返回Mono<Void>让Spring框架处理订阅和错误传播,绝对不能自己调用subscribe(),否则框架无法感知异常,也无法正确返回错误响应。修改后的代码如下:

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    String authHeaderSearch = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    
    // 直接返回Mono,由框架处理订阅
    return webClient.get()
            .uri(uriBuilder -> uriBuilder.path("/users/validate")
                    .queryParam("token", authHeaderSearch)
                    .build())
            .retrieve()
            .bodyToMono(String.class)
            // 捕获所有异常,转换为自定义异常
            .onErrorResume(Exception.class, throwable -> Mono.error(new CantValidateTokenException("令牌验证服务不可用")))
            // 验证成功后继续执行过滤器链
            .flatMap(validResult -> {
                log.info("Token check result is: " + validResult);
                return chain.filter(exchange);
            })
            // 处理自定义异常,返回错误响应
            .onErrorResume(CantValidateTokenException.class, ex -> {
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            });
}

关键说明

  • 响应式编程中,不要用传统的try-catch捕获异步流的错误,必须通过Reactor提供的onErrorResume、onErrorReturn、doOnError等操作符处理流中的错误。
  • 在Spring WebFlux/Gateway环境中,所有过滤器、控制器方法都应该返回Mono/Flux,由框架统一处理订阅和错误传播,手动调用subscribe()会脱离框架的错误处理机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:54:59