How to handle HTTP status code in Spring Webclient
Asked Answered
D

1

7

I'm stuck trying to do simple error handling when calling a remote service. The service returns a Map. The behaviour I'm looking for is:

  • HTTP 200 --> Return body (Map<String, String>).
  • HTTP 500 --> Throw a particular exception
  • HTTP 404 --> Simply return Null.

Here's my code:

private Map<String, String> loadTranslations(String languageTag) {
    try {
        WebClient webClient = WebClient.create(serviceUrl);
        Map<String, String> result = webClient.get()
            .uri("/translations/{language}", languageTag)
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .onStatus(httpStatus -> HttpStatus.NOT_FOUND.equals(httpStatus),
                clientResponse -> Mono.error(new MyServiceException(HttpStatus.NOT_FOUND)))
            .onStatus(HttpStatus::is5xxServerError, response -> Mono.error(new MyServiceException(response.statusCode())))
            .bodyToMono(Map.class)
            .block();

        return result;
    } catch (MyServiceException ex) {  // doesn't work as in reality it throws ReactiveException
        ....
    }
}

I don't know how to have the result of block() return NULL (or something that I can interpret as "404 was received"). The idea would be to just return NULL on 404 and throw an exception on 500.

I tried returning Mono.empty() but in that case the result variable contains the body of the response as Dictionary (I'm using standard Spring error bodies that contain timestamp, path, message).

What I'm doing wrong?

Thank you,

Desrochers answered 25/12, 2019 at 0:48 Comment(2)
I currently have this same problem, will report back if I find a solution. Pretty sure there should be an idiomatic way to do this.Acidophil
for 404 case you can return onStatus(httpStatus -> HttpStatus.NOT_FOUND.equals(httpStatus), clientResponse -> Mono.empty()) and then check if the value of one key inside the map is null. and if that is the case return nullHic
C
2

ResponseSpec class's onStatus method signature from Spring WebFlux 5.x

ResponseSpec onStatus(Predicate<HttpStatus> statusPredicate,
                Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction);

changed to

ResponseSpec onStatus(Predicate<HttpStatusCode> statusPredicate,
                Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction);

in Spring Web 6.x

May be while upgrading to JDK 17 you upgraded spring version as well.

So change HttpStatus::isError to HttpStatusCode::isError and the error should go away.

Crawford answered 14/8, 2023 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.