Reactive Streams Java:如何区分上游错误返回的False与正常结果?
问题分析
当前代码中,service.existsByName(name)调用出错时会通过onErrorResume返回false,但正常业务逻辑也可能返回false,导致下游runUpdateColumn无法区分这两种场景,错误场景和正常不存在的场景执行了相同的更新逻辑,不符合预期。
方案一:用封装类区分状态(推荐)
通过自定义封装类,明确区分「接口调用成功的结果」和「调用出错的状态」,避免布尔值的二义性。
1. 定义状态封装类
// 封装exists方法的执行状态与结果 class ExistsResult { private boolean callSuccess; // 是否调用成功 private boolean exists; // 仅当callSuccess为true时有效 private ExistsResult(boolean callSuccess, boolean exists) { this.callSuccess = callSuccess; this.exists = exists; } // 工厂方法:正常返回存在状态 public static ExistsResult success(boolean exists) { return new ExistsResult(true, exists); } // 工厂方法:调用出错 public static ExistsResult error() { return new ExistsResult(false, false); // exists字段无意义 } // getter方法 public boolean isCallSuccess() { return callSuccess; } public boolean isExists() { return exists; } }
2. 修改process方法
将原布尔值替换为封装类,错误分支返回错误状态,正常分支返回带业务结果的成功状态:
public Mono<User> process(String name, User userDetails) { return service.existsByName(name) .doOnError(WebClientRequestException.class, throwable -> log.error("Failed to find...", throwable) // 建议带上异常栈,方便排查问题 ) .map(isFound -> ExistsResult.success(isFound)) .onErrorResume(ex -> Mono.just(ExistsResult.error())) .flatMap(result -> runUpdateColumn(userDetails, result)); }
3. 修改runUpdateColumn方法
根据封装类的状态分别处理不同场景:
public Mono<User> runUpdateColumn(User userDetails, ExistsResult result) { if (result.isCallSuccess()) { // 正常业务场景:根据exists状态执行对应更新 service.updateColum(!result.isExists()); } else { // 错误场景:这里可以选择不执行更新,或者执行错误专属的更新逻辑 // 比如 service.updateColum(xxx); } return Mono.just(userDetails); }
方案二:拆分错误分支与正常分支(无需新增类)
如果不想新增类,可以直接把错误场景的逻辑单独放在onErrorResume中,和正常业务分支彻底分离:
public Mono<User> process(String name, User userDetails) { return service.existsByName(name) .doOnError(WebClientRequestException.class, throwable -> log.error("Failed to find...", throwable) ) // 正常业务分支:处理true/false的常规更新逻辑 .flatMap(isFound -> { service.updateColum(!isFound); return Mono.just(userDetails); }) // 错误分支:单独处理调用出错的情况,不与正常false混淆 .onErrorResume(ex -> { // 错误场景的处理逻辑:比如跳过更新,或者执行特定操作 // service.updateColum(xxx); return Mono.just(userDetails); }); }
这样修改后,错误场景会直接进入onErrorResume分支,正常返回false的情况进入flatMap分支,两者完全独立,不会再出现混淆。
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

