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

Spring WebFlux中Mono.zip异常如何不中断执行并获取成功调用结果

问题核心原因

  • Mono.zip 默认行为是只要任意参与组合的Mono发出错误信号,整个组合流会立刻触发错误回调,中断执行,错误会直接向下游传递,不会等待其他调用返回结果
  • onErrorContinue 不适用于当前场景:该操作符仅支持处理「上游已发出正常元素,下游处理元素时抛出异常」的场景,无法处理上游直接发出错误信号的情况

解决方案

步骤1:定义结果包装类

首先自定义一个可以同时容纳成功结果和异常信息的包装类,方便后续区分每个调用的状态:

public class CallResult {
    // 成功时返回的业务数据
    private Model successData;
    // 失败时捕获的自定义异常
    private CustomException error;

    public static CallResult success(Model data) {
        CallResult result = new CallResult();
        result.successData = data;
        return result;
    }

    public static CallResult error(CustomException e) {
        CallResult result = new CallResult();
        result.error = e;
        return result;
    }

    // 状态判断、getter方法自行补充
    public boolean isSuccess() {
        return error == null;
    }
}

步骤2:封装单个调用的错误捕获逻辑

在每个getCall调用层直接捕获异常,将错误信号转为正常的CallResult信号,不让错误流入Mono.zip:

private Mono<CallResult> wrapGetCall(String path) {
    return getCall(path)
            .map(CallResult::success)
            // 捕获自定义异常,转为错误状态的CallResult
            .onErrorResume(CustomException.class, e -> Mono.just(CallResult.error(e)));
}

步骤3:调整Mono.zip逻辑

用包装后的Mono<CallResult>进行组合,此时所有调用的错误都已经被提前处理,Mono.zip会等待两个调用全部完成后再返回结果:

Tuple2<CallResult, CallResult> result = Mono.zip(
                wrapGetCall(call1),
                wrapGetCall(call2)
        )
        .block();

// 分别处理两个调用的结果
CallResult call1Result = result.getT1();
if (call1Result.isSuccess()) {
    Model data1 = call1Result.getSuccessData();
    // 处理call1成功逻辑
} else {
    CustomException e1 = call1Result.getError();
    // 处理call1失败逻辑
}

// 同理处理call2的结果
CallResult call2Result = result.getT2();
// ...

简化方案(不需要异常详情场景)

如果你只需要判断调用是否成功,不需要拿到具体的异常信息,可以直接用Optional代替自定义包装类,简化代码:

private Mono<Optional<Model>> wrapGetCall(String path) {
    return getCall(path)
            .map(Optional::ofNullable)
            .onErrorResume(CustomException.class, e -> Mono.just(Optional.empty()));
}

注意事项

  • 该方案会等待所有调用全部执行完成(无论成功失败)后才会返回聚合结果,完全符合你需要的不中断执行、可获取所有调用结果的需求
  • 有更多调用需要组合时,对每个调用做相同的包装处理即可
  • onErrorResume是Spring WebFlux官方推荐的上游错误捕获操作符,不要使用onErrorContinue处理当前场景的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:45:05