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); }
几个注意点
- 原代码里的
flatmap要改成flatMap(首字母大写),不然编译通不过。 exchangeToMono的lambda在非错误分支必须有返回值,不然会报错,上面例子里返回了对应Void类型的Mono,你可以根据实际业务调整返回内容。- 如果还是希望外部catch块能处理某些未覆盖的异常,就保留catch块,
onErrorResume只处理你预期的异常类型即可。
内容的提问来源于stack exchange,提问作者ghostrider
相关产品推荐
相关产品推荐

