WebClienr: Error not handled when response is empty

Got an issue when using Spring WebClient to consume API.

Code is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WebClient.RequestBodySpec requestBodySpec = webClientBuilder.baseUrl(baseUrl).build().post().uri(uri);
return requestBodySpec.exchangeToMono(clientResponse -> {
if (clientResponse.statusCode().is2xxSuccessful()) {
log.info("Successful {} for {}", clientResponse.statusCode().value(), clientResponse.request().getURI());
return clientResponse.bodyToMono(String.class);
} else {
log.warn("Non-successful code {} for {}", clientResponse.statusCode().value(), clientResponse.request().getURI());
return clientResponse.bodyToMono(String.class)
.flatMap(error -> Mono.error(new HttpException(HttpStatus.valueOf(clientResponse.statusCode().value()),
"Upstream Error",
clientResponse.statusCode().toString(),
error)
));
}
});

After testing, the behavior is:

  • For 2XX response, no prolem and can get the response.
  • Some 4XX/5XX response, some requeses can get the HttpException with details
  • Some 4XX/5XX response, some requests can NOT get the HttpException.

After some checkings, it shows that

  • If the remote server responses a response with body (Like an error message), no probme;
  • If the remote server response an error status but no body, this issue happens.

After some tries, the solution is that to provide a default response when the real response is empty (To let the reactive flow to move on):

1
2
3
4
5
6
7
return clientResponse.bodyToMono(String.class)
.defaultIfEmpty("<Empty>")
.flatMap(error -> Mono.error(new HttpException(HttpStatus.valueOf(clientResponse.statusCode().value()),
"Upstream Error",
clientResponse.statusCode().toString(),
error)
));