Home > Software design >  Reactor: then() is called even though error is occured
Reactor: then() is called even though error is occured

Time:10-13

Following code makes me confused

doSomething()
.then(doSomethingElse())
    .onErrorResume(throwable -> {
        System.out.println("Error occurred");
        return Mono.empty();
    })

private Mono<Void> doSomething() {
    System.out.println("Error thrown");
    return Mono.error(new RuntimeException());
}

private Mono<Void> doSomethingElse() {
    System.out.println("doSomethingElse");
    return Mono.empty();
}

output:

Error thrown
doSomethingElse
Error occurred

Why then() is called when error is returned, shouldn't it be skipped? I expect following output:

Error thrown
Error occurred

What is proper way to achieve expected behavior? In other words, then() should be called only when doSomeError doesn't produce any errors.

CodePudding user response:

then(Mono<V> other) takes an existing publisher, ignores all of its elements, and then propagates the completion signal. The error signal is replayed in the resulting Mono, which is why the .onErrorResume method is triggered in your snippet.

You should use Mono.concatWith operator like this:

doSomething()
    .concatWith(doSomethingElse())
    .onErrorResume(throwable -> {
        System.out.println("Error occurred");
        return Mono.empty();
    })

CodePudding user response:

Since doSomethingElse is called during the creation of the stream itself, you sould change the function as follows to get the expected result;

   private Mono<Void> doSomethingElse() {
        return Mono.fromSupplier(() -> {
            System.out.println("doSomethingElse");
            return null;
        });
    }
  • Related