Home » Java » Project reactor: onErrorResume after flatMap

Project reactor: onErrorResume after flatMap

Posted by: admin December 28, 2021 Leave a comment

Questions:
Flux.just("a", "b")
        .flatMap(s -> s.equals("a") ? Mono.error(new RuntimeException() : Flux.just(s + "1", s + "2"))
        .onErrorResume(throwable -> Mono.empty())
        .subscribe(System.out::println);

Hello!

Here I made a flux of two elements and then expose by flatMap first one to exception, and second one to another Flux.

With onErrorResume I expect the output

b1
b2

but get nothing. Could anyone explain why does it happens, please?

Thanks.

Answers:

Given this:

Flux.just("a", "b", "c")
        .flatMap { s ->
            if (s == "b") 
                Mono.error<RuntimeException>(RuntimeException()) 
            else 
                Flux.just(s + "1", s + "2")
        }.onErrorResume { throwable -> Mono.just("d") }.log()
        .subscribe { println(it) }

The output is:

12:35:19.673 [main] INFO reactor.Flux.OnErrorResume.1 - onSubscribe(FluxOnErrorResume.ResumeSubscriber)
12:35:19.676 [main] INFO reactor.Flux.OnErrorResume.1 - request(unbounded)
12:35:19.677 [main] INFO reactor.Flux.OnErrorResume.1 - onNext(a1)
a1
12:35:19.677 [main] INFO reactor.Flux.OnErrorResume.1 - onNext(a2)
a2
12:35:19.712 [main] INFO reactor.Flux.OnErrorResume.1 - onNext(d)
d
12:35:19.713 [main] INFO reactor.Flux.OnErrorResume.1 - onComplete()

What’s going on here? onErrorResume() is being applied to the Publisher returned by the flatMap() operator. Since on “b” the Publisher signals a failure, the flatMap() Publisher doesn’t execute anymore and onErrorResume() operator keeps publishing using its fallback.

The documentation for onErrorResume() shows clearly that the original Publisher finishes because of the error and the fallback takes over:

enter image description here

###

This question has already a solid answer by codependent why this happens. To answer a little off-topic how to achieve the expected output:

The onErrorResume call has to be moved into the flatMap:

Flux.just("a", "b")
    .flatMap(s ->
        (s.equals("a") ? Mono.error<RuntimeException>(RuntimeException()) : Flux.just(s + "1", s + "2"))
             .onErrorResume(ex -> Mono.empty())
    )
    .subscribe(System.out::println)

This way the output is as expected

b1
b2