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()); }
为什么之前的写法无效?
- 外层同步try/catch:
productRepository.insert()返回的是Mono,这个操作不会立即执行,而是在下游订阅时才触发。外层的try/catch在流尚未执行时就已经结束,根本抓不到后续异步抛出的异常。 - 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
相关产品推荐
相关产品推荐

