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

WebClient中doOnError处理后仍抛出异常的问题咨询

WebClient doOnError后异常仍抛出的原因及解决办法

问题根源

doOnError只是个副作用操作——它只会在异常出现时帮你执行额外逻辑(比如打日志),但根本不会“吃掉”异常。异常还是会顺着Reactor流继续往下传,等你调用block()的时候,这个异常就会被抛出来,自然就触发外部的catch块了。

解决办法

要想让异常不传到外部catch块,得用真正能处理异常的操作符,比如onErrorResume,它能捕获异常、执行自定义逻辑,然后返回一个正常的Mono来终止异常传播。

修正后的代码

try {
    getWebClient()
        .patch()
        .uri(uri)
        .body(fromValue(getBody()))
        .exchangeToMono(clientResponse -> {
            if (clientResponse.statusCode().isError()) {
                return clientResponse.bodyToMono(APIresponse.class)
                    .switchIfEmpty(Mono.error(new WebClientResponseException(
                        clientResponse.statusCode().value(),
                        clientResponse.statusCode().getReasonPhrase(),
                        null, null, Charset.defaultCharset()
                    )))
                    .flatMap(apiresponse -> Mono.error(new WebClientResponseException(
                        clientResponse.statusCode().value(),
                        apiresponse.getResponseMessage(),
                        null, null, Charset.defaultCharset()
                    )));
            }
            // 这里必须补充正常响应的处理逻辑,比如返回空Mono或者对应实体
            return clientResponse.bodyToMono(Void.class);
        })
        // 用onErrorResume替代doOnError,处理异常并终止传播
        .onErrorResume(throwable -> {
            log.error("Error Text {}", throwable.getMessage());
            return Mono.empty();
        })
        .block();
} catch (Exception exception) {
    log.error("Exception from api call", exception);
}

几个注意点

  1. 原代码里的flatmap要改成flatMap(首字母大写),不然编译通不过。
  2. exchangeToMono的lambda在非错误分支必须有返回值,不然会报错,上面例子里返回了对应Void类型的Mono,你可以根据实际业务调整返回内容。
  3. 如果还是希望外部catch块能处理某些未覆盖的异常,就保留catch块,onErrorResume只处理你预期的异常类型即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:15:35