Search code examples
javaspring-webfluxreactivespring-webclient

Exception from a Spring WebFlux Mono interrupts Mono.zip


Let's say that I have two calls using spring webclient. Both are defined as follow, with an exception thrown in .onStatus :

public Mono<Model> getCall(String path) {
    webClient.get()
            .uri(path)
            .retrieve()
            .onStatus(HttpStatus::isError, errorHandler())}

And this is the Exception function errorHandler() :

private Function<ClientResponse, Mono<? extends Throwable>> errorHandler() {
    return clientResponse -> clientResponse.bodyToMono(ErrorResponse.class).
            flatMap(errorBody -> Mono.error(new CustomException(clientResponse.statusCode().value(), "exception", errorBody)));

On my Mono.zip, I defined it as follow :

Mono.zip(getCall(call1),
         getCall(call2))
         .block;

The problem is, if one of the calls throws an exception, I can no longer get at least one of the result. Tried using :

.onErrorContinue(CustomException.class, (error, output) -> log.error("CustomException !" + error + output))

So how can I handle exceptions with Mono.zip, like we do with try catch, but without stopping the execution and getting the results of successful calls ? And Thank you


Solution

  • If your output has an empty state you can do something like:

    .onErrorResume(CustomException.class, e -> Model.empty())
    

    If you don't have empty state you should wrap the output into Optional:

    .map(Optional::of)
    .onErrorResume(CustomException.class, e -> Optional.empty())
    

    In any case these operators should be chained to the getCall method. For example:

    public Mono<Model> getCall(String path) {
        return webClient.get()
                .uri(path)
                .retrieve()
                .onStatus(HttpStatus::isError, errorHandler())     
                .retrieve()
                .bodyToMono(Model.class)
                .onErrorResume(CustomException.class, e -> Model.empty());
    }