Spring WebFlux WebClient无法捕获异常问题求助
问题排查与解决方案
核心问题原因
- 响应式异步特性导致try-catch失效:
try-catch只能捕获当前线程同步执行的异常,而WebClient的响应式操作(Mono)是延迟异步执行的,只有调用subscribe()后才会真正发起请求,错误会在异步线程中抛出,根本不会进入外层的try-catch块。 - 未正确处理订阅阶段的错误:你虽然用
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
相关产品推荐
相关产品推荐

