When using the retrieve() method of Spring WebClient in conjunction with bodyToMono default error handling is applied (if the response has status code 4xx or 5xx, the Mono will contain a WebClientException). In error cases the resulting WebClientException is very helpful because it contains the request AND the response, which is very convenient e.g. for logging. Furthermore, I can react to errors very nicely in place.
/*
* Easy to use retrieve() with default error handling:
* By default, if the response has status code 4xx or 5xx, the Mono will contain a WebClientException - AWESOME!
*/
public Optional<MyType> getMyType() {
try {
MyType result = client
.get()
.uri("/myType")
.retrieve().bodyToMono(MyType.class).block();
return Optional.ofNullable(result);
} catch (NotFound e) {
return Optional.empty();
}
}
However, sometimes I need to know the exact status code of the response to react to it when further processing this response. The only method to also get the status code is to call the exchange() Method instead of the retrieve() Method. Unfortunately, in that case the default error handling is not applied. The reason for that seems to be that calling bodyToMono() on ClientResponse has a different semantics than calling it on ResponseSpec.
I cannot call the already implemented Methods from Spring to "trigger" the error handling because all the nice methods are buried as private in the WebClient.
Even if I would try to "manually" create a WebClientResponseException I cannot access the request to feed to the exception.
public String updateMyType() {
ClientResponse response = client
.put()
.uri("/myType")
.header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.body(fromObject(new MyType()))
.exchange()
.block();
if (response.statusCode().equals(HttpStatus.CREATED)) {
return "OK";
} else if (response.statusCode().equals(HttpStatus.NO_CONTENT)) {
return "updated";
} else {
byte[] bodyBytes = null; // already implemented by Sping but not accessible
Charset charset = null; // already implemented by Sping but not accessible
HttpRequest request = null; // where should I get this from?
throw WebClientResponseException.create(response.statusCode().value(),
response.statusCode().getReasonPhrase(),
response.headers().asHttpHeaders(),
bodyBytes,
charset,
request);
}
}
What is the best way to “mimic” the same behavior as for the retrieve() Method?