1

I need to catch MonoError and stop an application with ErrorResponse, but the application works as I did not expect.

My code:

return checkText(text)
                .then(getWordsFromText(text))
                .map(keyWords -> new SuccessfulResponse(keyWords))
                .onErrorResume(
                        throwable -> {
                            return Mono.just(new ErrorResponse(throwable.getMessage()));
                        });

public Mono<Void> checkText(String text) {
        if (text == null) {
            return Mono.error(new Exception("wrong text"));
        } 
        return Mono.empty();
    }

my problem is that if text param is null -> I fall into getWordsFromText method. This is an incorrect execution, because if the text parameter is equal to null, then the application must exit with an error (with ErrorResponse).

I fixed it as (replacing 'then' to 'flatMap'):

return checkText(text)
                .flatMap(voidParam -> getWordsFromText(text)) //replaced 'then' to 'flatMap'
                .map(keyWords -> new SuccessfulResponse(keyWords))
                .onErrorResume(
                        throwable -> {
                            return Mono.just(new ErrorResponse(throwable.getMessage()));
                        });

and now it's working correctly. If text param is null I miss the call getWordsFromText method and fall in error handling (onErrorResume).

But I think using flatMap in my case is not a good idea, I don't like how it looks: .flatMap(voidParam -> ...

Can you have any ideas how possible to do better? (without 'flatMap')

Julia
  • 81
  • 1
  • 6
  • 2
    I recommend checking this answer: https://stackoverflow.com/questions/57870706/whats-the-point-of-switchifempty-getting-evaluated-eagerly/57877616#57877616 – Martin Tarjányi Oct 26 '21 at 11:59

1 Answers1

1

In the first snippet, the call to getWordsFromText() is made while building your main reactive pipeline, before it is even subscribed to (i.e. at assembly time). The reason it works as intended in the second snippet is that flatMap only creates the inner publishers (and subsequently subscribes to them) as it receives elements from upstream (i.e. at subscription time).

In this case if you want to replace the flatMap you could try this: .then(Mono.fromCallable(() -> getWordsFromText(text)))