Reactive Mono未传播自定义异常的问题及诉求
问题分析与解决方案
你的代码中异常无法传播到父方法的核心原因有两个:
- subscribe的异步特性:
subscribe触发的是异步订阅,回调逻辑在独立线程执行,父方法abc()会在订阅后直接返回,回调中抛出的异常无法同步传递到父方法的调用栈中。 - ErrorDropped Hook的错误使用:在
Hooks.onErrorDropped中抛出异常会被Reactor框架捕获,进而再次触发onErrorDropped,导致无限循环打印日志,同时异常也无法向外传播。
解决方案
方案1:同步阻塞获取结果(适合必须同步抛出异常的场景)
将subscribe替换为block(),同步等待Mono执行完成,此时异常会被包装为RuntimeException,你可以捕获后转换为CustomException抛出:
void abc() throws CustomException { Mono<String> response = getXXResponse(); try { String res = response.block(); // 成功逻辑 .....logic in success case } catch (RuntimeException e) { logger.info("in error handler"); throw new CustomException("ERROR"); } }
方案2:保持响应式风格(推荐)
将abc()方法改为返回Mono<Void>,让上层调用方处理异常,符合Reactor的响应式设计原则:
Mono<Void> abc() { return getXXResponse() .doOnNext(res -> { // 成功逻辑 .....logic in success case }) .doOnError(throwable -> { logger.info("in error handler"); }) .onErrorMap(throwable -> new CustomException("ERROR")); }
上层调用方可以通过subscribe或block()处理这个返回的Mono,异常会正常传递:
// 上层调用示例 try { abc().block(); } catch (CustomException e) { // 处理CustomException }
注意事项
- 移除
Hooks.onErrorDropped的错误配置,避免异常循环传播。 - 响应式编程中优先使用方案2,同步阻塞(block())仅在非响应式环境的适配场景下使用。
内容的提问来源于stack exchange,提问作者Nalini Wanjale
相关产品推荐
相关产品推荐

