4

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();
}
heldt
  • 4,166
  • 7
  • 39
  • 67

2 Answers2

13

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();
}
A developer
  • 290
  • 3
  • 11
  • Note that the "onStatus" calls are not necessary to solve the original problem. The "onErrorResume" call does the requested job. – Joachim Lous Mar 04 '22 at 14:40
2

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));
flok
  • 21
  • 2