6

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,

tggm
  • 973
  • 2
  • 15
  • 41
  • 1
    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. – Bart Enkelaar Nov 27 '20 at 11:14
  • 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 null – Yehouda May 18 '22 at 10:41

1 Answers1

0

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.

krishnakumarp
  • 8,967
  • 3
  • 49
  • 55