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
相关产品推荐
相关产品推荐

