如何在Project Reactor中遇特定错误时终止流?
处理Reactor流中的特定错误过滤
要实现“遇到特定错误终止流、其他错误正常传播”的需求,你需要用能改变流状态的错误处理操作符,而不是仅做副作用的doOnError,同时onErrorContinue并不适用于你的场景,原因和解决方案如下:
问题分析
doOnError只是监听错误并执行副作用,不会改变流的错误状态,所以错误依然会向上传播,达不到“终止流且不传播错误”的效果。onErrorContinue是为Flux批量处理设计的,用于跳过错误元素继续处理下一个,对Mono(单元素流)不适用;另外如果你的NotFound异常被包装在其他异常(如WebClientResponseException)中,直接用it instanceof NotFound会匹配失败。
正确解决方案
方案1:用onErrorResume精准捕获特定异常
onErrorResume可以捕获指定类型的异常,并返回一个新的正常流来替代错误流,从而终止当前分支且不传播错误:
Mono<Void> call() { return service.find() .filter(...) // 保留你的原有过滤逻辑 .flatMap(item -> otherService.find() // 捕获NotFound异常,返回empty()让流正常终止 .onErrorResume(NotFound.class, err -> { log.info("遇到NotFound错误,终止流: {}", err.getMessage()); return Mono.empty(); }) .flatMap(...) // 保留你的后续处理逻辑 .then() ) .then(); }
当otherService.find()抛出NotFound时,onErrorResume会拦截它,返回Mono.empty()使当前流正常完成,不会标记为错误;其他类型的异常会继续向上传播。
方案2:针对HTTP状态码处理(如果用WebClient调用API)
如果你的NotFound是对应HTTP 404状态码,可以直接用onErrorStatus匹配状态码:
Mono<Void> call() { return service.find() .filter(...) .flatMap(item -> otherService.find() .onErrorStatus(HttpStatus.NOT_FOUND, err -> { log.info("请求返回404,终止流: {}", err.getMessage()); return true; // 确认匹配该状态码 }) .flatMap(...) .then() ) .then(); }
处理包装后的异常
如果NotFound被包装在其他异常(如WebClientResponseException)中,需要先拆包再判断:
Mono<Void> call() { return service.find() .filter(...) .flatMap(item -> otherService.find() .onErrorResume(err -> { // 检查是否是包装了404的WebClient异常 if (err instanceof WebClientResponseException webEx && webEx.getStatusCode() == HttpStatus.NOT_FOUND) { log.info("捕获404错误: {}", webEx.getMessage()); return Mono.empty(); } // 其他异常继续抛出 return Mono.error(err); }) .flatMap(...) .then() ) .then(); }
内容的提问来源于stack exchange,提问作者Rafa Acioly
相关产品推荐
相关产品推荐

