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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:00:00