When calling a remote service, it's important to know if an exception happened before sending the request or after receiving the response.
Unfortunately, not all exceptions are wrapped by WebClientResponseException
, WebClientException
or another subclass of WebClientException
when calling webClient.retrieve().bodyToFlux()
resp. webClient.retrieve().bodyToMono()
E.g.:
Before request:
- java.net.ConnectException
- io.netty.channel.ConnectTimeoutException
- io.netty.handler.timeout.ReadTimeoutException
After response:
- org.springframework.core.codec.DecodingException
org.springframework.core.codec.CodecException
could happen before request and after response, I guess. How can we detect this?
I also might have missed some exceptions.
Exception handling would be much easier if the following rule could be implemented:
if the exception happens after the response -> wrap the exception with a WebClientResponseException
, so we don't loose the http status code and the payload
else wrap the exception with a WebClientException
or another subclass.
I'm not sure if this a bug or an enhancement request.
Comment From: poutsma
Team Decision: It makes sense to handle, wrap and re-emit the different connection exceptions, but doing so will change backwards compatibility and might break users' existing connection-handling code. So we cannot do this until 5.3 at least.
As for wrapping in a WebClientResponseException
: we can only consume the response body once, so once the decoder has partially done so but throws a DecodingException
, we cannot consume that body again to put it in the WebClientResponseException
. So that would only leave the status code, which is probably not that useful, as it is probably going to be 200.
Finally, I am not so sure if the wrapping and re-throwing pattern is as useful for onError*
method as it is for catch
clauses. In a catch clause, it is convenient to catch a general exception for all possible errors, but I don't think the same holds true for an onErrorResume
.