I cannot understand how Flux.onErrorContinue()
works. Based on Does Reactor onErrorContinue operator let the original sequence continue? I created a similar example to understand it better, but I am lost.
Especially weird is the interference between onErrorContinue()
and thenReturn()
.
I have the following code:
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
class OnErrorContinueTest {
@Test
void testOnErrorContinue() {
Flux.range(1, 3)
.doOnNext(n -> System.out.println("Main-1: " + n))
.flatMap(this::processElement)
.doOnNext(n -> System.out.println("Main-2: " + n)) // Why does onErrorContinue recovers that line, if it is after?
.onErrorContinue((ex, o) -> System.err.println(" Error processing " + o + " - " + ex.getMessage()))
.doOnNext(n -> System.out.println("Main-3: " + n))
.subscribe();
}
@Test
void testOnErrorResume() {
Flux.range(1, 3)
.doOnNext(n -> System.out.println("Main-1: " + n))
.flatMap(n -> this.processElement(n)
.doOnError(ex -> System.err.println(" Error processing " + n + " - " + ex.getMessage()))
.onErrorResume(e -> Mono.empty()))
.doOnNext(n -> System.out.println("Main-2: " + n))
.subscribe();
}
Mono<Integer> processElement(Integer i) {
return Mono.just(i)
.doOnNext(n -> System.out.println(" Process-1: " + n))
.doOnNext(n -> {
if (n == 2) {
throw new RuntimeException("Forcing exception for " + n);
}
})
.doOnNext(n -> System.out.println(" Process-2: " + n))
.thenReturn(i) // Why does onErrorContinue recovers everything after that line?
.doOnNext(n -> System.out.println(" Process-3: " + n))
;
}
}
testOnErrorResume()
produces exactly what I would expect:
Main-1: 1
Process-1: 1
Process-2: 1
Process-3: 1
Main-2: 1
Main-1: 2
Process-1: 2
Error while processing 2 - Forcing exception for 2
Main-1: 3
Process-1: 3
Process-2: 3
Process-3: 3
Main-2: 3
However, testOnErrorContinue()
produces:
Main-1: 1
Process-1: 1
Process-2: 1
Process-3: 1
Main-2: 1
Main-3: 1
Main-1: 2
Process-1: 2
Error while processing 2 - Forcing exception for 2
Process-3: 2 -- UNEXPECTED - WHY IS THIS PRINTED?
Main-2: 2 -- UNEXPECTED - WHY IS THIS PRINTED?
Main-3: 2
Main-1: 3
Process-1: 3
Process-2: 3
Process-3: 3
Main-2: 3
Main-3: 3
My doubts:
Why does
onErrorContinue()
recover inside theprocessElement()
method? It seems likethenReturn()
has something to do with it, but cannot understand how, because thethenReturn()
s documentation statesOn an error in the original
Mono
, the error signal is propagated instead.Why does
onErrorContinue()
recover before it is called? Why is the codeSystem.out.println("Main-2: " + n)
executed?