How to handle 404 in webclient retrive
Asked Answered
S

3

14

I am new to spring webclient and i have written a generic method which can be used to consume rest apis in my application:

public <T> List<T> get(URI url, Class<T> responseType) {
        return  WebClient.builder().build().get().uri(url)
                   .header("Authorization", "Basic " + principal)
                   .retrieve().bodyToFlux(responseType).collectList().block();
}

i wanted to return and empty list if consumed rest-api return 404.

can someone suggest how to achieve that?

Shall answered 10/5, 2021 at 11:37 Comment(0)
R
11

By default retrieve method throws WebClientResponseException exception for any 4xx & 5xx errors

By default, 4xx and 5xx responses result in a WebClientResponseException.

You can use onErrorResume

 webClient.get()
 .uri(url)
 .retrieve()
 .header("Authorization", "Basic " + principal)
 .bodyToFlux(Account.class)
 .onErrorResume(WebClientResponseException.class,
      ex -> ex.getRawStatusCode() == 404 ? Flux.empty() : Mono.error(ex))
 .collectList().block();
Repellent answered 10/5, 2021 at 11:53 Comment(0)
C
4

You can also use onStatus it allow you to filter exceptions you want

public <T> List<T> get(URI url, Class<T> responseType) {
    return  WebClient.builder().build().get().uri(url)
            .header("Authorization", "Basic " + principal)
            .retrieve()
            .onStatus(HttpStatus::is4xxClientError, this::handleErrors)
            .bodyToFlux(responseType)
            .collectList().block();
}

private Mono<Throwable> handleErrors(ClientResponse response ){
    return response.bodyToMono(String.class).flatMap(body -> {
        log.error("LOg errror");
        return Mono.error(new Exception());
    });
}
Consult answered 10/5, 2021 at 13:11 Comment(1)
Will it produce an exception or an empty list on 404 response at block()?Buskined
G
3

As of Spring WebFlux 5.3 they've added the exchange methods which allows you to easily handle different responses, like this:

public <T> List<T> get(URI url, Class<T> responseType) {
    return WebClient.builder().build().get().uri(url)
        .header("Authorization", "Basic " + principal)
        .exchangeToFlux(clientResponse -> {
            if (clientResponse.statusCode().equals(HttpStatus.NOT_FOUND)) {
                return Flux.empty();
            } else {
                return clientResponse.bodyToFlux(responseType);
            }
        })
        .collectList()
        .block();
}
Gillis answered 10/2, 2022 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.