onErrorContinue()与thenReturn()的干扰问题及原理疑惑
我在探究Flux.onErrorContinue()的工作机制时编写了测试案例,发现它与Mono.thenReturn()存在异常干扰现象。测试代码包含testOnErrorContinue()和testOnErrorResume()两个方法,其中processElement()方法会在n=2时抛出异常。testOnErrorResume()的输出符合预期,但testOnErrorContinue()出现两处不符合预期的行为:
- 异常发生后,
processElement()中的Process-3:2被打印; - 异常发生后,
Main-2:2和Main-3:2被打印。
针对这两个现象,下面拆解背后的逻辑:
疑惑点1:onErrorContinue()为何能恢复processElement()方法内的执行?
onErrorContinue()的核心是序列中某个元素处理出错时,跳过该错误元素,继续处理后续元素,但它的生效逻辑会渗透到当前Flux链嵌套的操作符上下文里。
当processElement()中前置Mono抛出异常后,onErrorContinue()会捕获这个错误,并触发"继续"信号——这个信号会让当前元素的处理流程继续执行后续代码,包括thenReturn()之后的Process-3打印。而thenReturn()文档中"原Mono出错时传播错误信号"的描述,是在没有onErrorContinue()干预的前提下的行为——onErrorContinue()的错误拦截优先级更高,直接覆盖了thenReturn()原本的错误传播逻辑。
疑惑点2:onErrorContinue()为何能恢复其调用前的代码执行?
Main-2:2这类调用前的代码被执行,是因为onErrorContinue()的恢复逻辑作用于整个元素的处理周期,而非仅作用于它之后的操作符。
当n=2的元素处理出错时,onErrorContinue()触发后,不会直接终止当前元素的处理链,而是尝试让该元素的整个处理流程走完,之后再丢弃这个错误元素、继续下一个元素。所以onErrorContinue()调用前的Main-2、Main-3打印代码会被执行。
对比onErrorResume(),它的逻辑是错误发生时用新序列替换出错的原序列,不会让原出错的处理流程继续执行,因此不会出现这类额外打印。
内容的提问来源于stack exchange,提问作者Honza Zidek

