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

Spring Webflux flatMap内部Mono抛出异常未被主响应流处理如何解决

问题根因与解决方案

你遇到的问题核心来自两个常见的响应式编程误区,修正后即可让异常被外层流水线正常捕获:

1. 先修正基础代码错误

你给出的示例代码首先存在返回值类型不匹配的问题:getData方法实际返回的是Mono<String>,但你声明的返回值是String,这会导致流组装直接失败,错误逻辑根本没有机会生效。

修正后的完整代码示例如下:

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Example {
    private final WebClient webClient = WebClient.create("你的请求地址前缀");

    // 修正返回值为Mono<String>
    public Mono<String> getData(String name) {
        return Mono.just(name)
                .map(String::toLowerCase)
                .flatMap(lowerName -> 
                    // 补全完整的WebClient调用逻辑
                    webClient.get()
                            .uri("/xxx?name={name}", lowerName)
                            .retrieve()
                            .bodyToMono(String.class)
                            .doOnSuccess(Validator::validateData)
                )
                // 外层的错误处理可以正常捕获flatMap内部产生的所有异常
                .doOnError(ex -> log.error("Got an error, {}", ex.getMessage(), ex))
                .onErrorMap(ex -> new AnotherCustomException(ex.getMessage()));
    }
}

class Validator {
    public static void validateData(String data) {
        if(data.length() < 5) {
            throw new CustomException("Invalid data received.");
        }
    }
}

// 自定义异常定义示例
class CustomException extends RuntimeException {
    public CustomException(String message) {
        super(message);
    }
}

class AnotherCustomException extends RuntimeException {
    public AnotherCustomException(String message) {
        super(message);
    }
}

2. 确保订阅时配置错误回调

绝大多数情况下,外层错误算子不生效的核心原因是订阅时没有指定错误处理回调:
如果你的调用方式是getData("test").subscribe(data -> 处理返回值),没有加第二个错误回调参数,那么流内的异常会被Reactor底层直接抛出到调用线程,打印堆栈,不会触发你定义的onErrorMap等逻辑。

正确的订阅方式如下:

getData("test")
    .subscribe(
        data -> {
            // 正常处理返回结果
            System.out.println("获取到数据:" + data);
        },
        ex -> {
            // 处理最终的异常
            System.out.println("捕获到最终异常:" + ex.getMessage());
        }
    );

补充说明

flatMap会自动将内部Publisher的错误信号传递到外层流水线,不需要在内部Mono单独加错误处理算子,只要你的流组装正确、订阅时配置了错误回调,内部WebClient请求抛出的异常、校验抛出的CustomException都会被外层的doOnError、onErrorMap正常处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:06:02