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

WebFlux服务层如何在Mono流中向调用者抛出自定义异常?

WebFlux服务层MongoDB重复键异常处理方案

你之前的写法错误在于用同步try/catch处理响应式流中的异常——响应式操作是异步执行的,同步代码块根本捕获不到流执行时抛出的异常。正确的做法是使用WebFlux提供的响应式异常处理操作符onErrorMap。

正确实现代码

public Mono<ProductDto> insertProduct(Mono<ProductDto> in) {
    return in.map(ProductDto::toEntity)
            .flatMap(productRepository::insert)
            .map(ProductDto::new)
            // 捕获DuplicateKeyException并转换为自定义异常
            .onErrorMap(DuplicateKeyException.class, ex -> new ProductAlreadyExistsException());
}

为什么之前的写法无效?

  1. 外层同步try/catch:productRepository.insert()返回的是Mono,这个操作不会立即执行,而是在下游订阅时才触发。外层的try/catch在流尚未执行时就已经结束,根本抓不到后续异步抛出的异常。
  2. flatMap内的try/catch:同样的问题,productRepository.insert(p)返回的是Mono,异常不会在调用方法时抛出,而是在Mono的订阅阶段触发,所以这个try/catch也捕获不到异常。

扩展:复杂异常处理

如果需要添加日志或更精细的异常判断,可以在onErrorMap中编写逻辑:

.onErrorMap(DuplicateKeyException.class, duplicateEx -> {
    // 记录异常日志
    log.error("插入产品时遇到重复键异常,异常信息: {}", duplicateEx.getMessage());
    // 返回带详细信息的自定义异常
    return new ProductAlreadyExistsException("该产品ID已被使用", duplicateEx);
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:07:07