Convenience API for custom error handling on WebClient [SPR-15724]
See original GitHub issueDoron Gold opened SPR-15724 and commented
It would be very helpful to have a way to set custom error handling for WebClient responses. This could be done by providing methods that allow developers to map each desired response code to an error handling Function.
Code that uses such functionality could look similar to the following:
Mono<ExampleResponse> exampleResponse = webClient.get()
.uri("http://spring.io/example")
.exchange()
.onStatusCode(HttpStatus.FORBIDDEN, (ClientResponse clientResponse) -> {
return new CustomException("Access Forbidden");
})
.on4xx((ClientResponse clientResponse) -> {
return new CustomException("Client Error");
})
.on5xx((ClientResponse clientResponse) -> {
return new CustomException("Server Error");
})
.flatMap(clientResponse -> clientResponse.bodyToMono(ExampleResponse.class));
Mono<ExampleResponse2> exampleResponse2 = webClient.get()
.uri("http://spring.io/example2")
.exchange()
.onStatusCode(HttpStatus.FORBIDDEN, (ClientResponse clientResponse) -> {
return new CustomException("Access Forbidden");
})
.onStatusCode(HttpStatus.INTERNAL_SERVER_ERROR, (ClientResponse clientResponse) -> {
return new CustomException("Internal Error");
})
.on4xx5xx((ClientResponse clientResponse) -> {
return new CustomException("General Error");
})
.flatMap(clientResponse -> clientResponse.bodyToMono(ExampleResponse2.class));
In the example above the onStatusCode
method receives a status code and a Function. The specified status code maps to the specified Function. The Function is of the following type:
Function<ClientResponse, ? extends Throwable>
In case the returned response code matches, the appropriate Function is applied and an error Mono that wraps the Throwable returned by the Function is emitted.
The variants on4xx
, on5xx
, and on4xx5xx
provide a “catch all” ability. They map a range of status codes to a Function.
Affects: 5.0 RC2
Issue Links:
- #20379 WebClientException should allow access to status code of the response
3 votes, 5 watchers
Issue Analytics
- State:
- Created 6 years ago
- Comments:20
Rossen Stoyanchev commented
Do you actually mean for this to be per-request error handling or global, onStatus handlers? In Arjen’s example the filter is declared on the builder, and therefore only once, and you can shorten it further with a static import. It’s not something that you type for every request.
If what you mean is per-request error handling why do you even need onStatusCode vs doing it inside the flatMap (as shown below)? After all this is one reason for using exchange + flatMap vs
retrieve
which is more streamlined but less control.Doron Gold commented
In order to be able to examine the body of the response before building the
Throwable
, maybe it is possible to add another signature toonStatus
that builds aMono
instead of aThrowable
. The purpose of thatMono
is to hold theThrowable
. The new signature can look like this:With the above method in place, application code could do something like the following: