Webclient returning Optional.empty() on not found response

Viewed 4221

I'm trying to make WebClient return an Optional.empty() when I get a 404, not found, from the server. But instead I get a Optional with a User object with all properties set to null.

What am I missing?

@Override
public Optional<User> getUser(Username username) {
    return webClient
            .get()
            .uri(buildUrl(username))
            .retrieve()
            .onStatus(HttpStatus.NOT_FOUND::equals, response -> Mono.empty())
            .onStatus(HttpStatus::is4xxClientError, response -> createError(response, CLIENTERROR))
            .onStatus(HttpStatus::is5xxServerError, response -> createError(response, SERVRERROR))
            .bodyToMono(User.class)
            .blockOptional();
}
2 Answers

You can make use of onError* functions from Mono to handle these cases.

onErrorResume to create a empty/error Mono on exception and onErrorMap to transform exception to a different exception type.

For example:

@Override
public Optional<User> getUser(Username username) {
    return webClient
            .get()
            .uri(buildUrl(username))
            .retrieve()
            .onStatus(httpStatus -> httpStatus.is4xxClientError() && httpStatus != HttpStatus.NOT_FOUND, response -> createError(response, CLIENTERROR))
            .onStatus(HttpStatus::is5xxServerError, response -> createError(response, SERVRERROR))
            .bodyToMono(User.class)
            .onErrorResume(WebClientResponseException.NotFound.class, notFound -> Mono.empty())
            .blockOptional();
}

Have a look at the sample code from WebClient Javadoc (javadoc). It does exactly that using Mono's onErrorResume Method:

 webClient.get()
   .uri("https://example.com/account/123")
   .retrieve()
   .bodyToMono(Account.class)
   .onErrorResume(WebClientResponseException.class,
        ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex));
Related