question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Convenience API for custom error handling on WebClient [SPR-15724]

See original GitHub issue

Doron 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:closed
  • Created 6 years ago
  • Comments:20

github_iconTop GitHub Comments

3reactions
spring-projects-issuescommented, Jan 11, 2019

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.

Mono<ExampleResponse> exampleResponse = webClient.get()
                .uri("http://spring.io/example")
                .exchange()
                .flatMap(clientResponse -> {
                     if (response.statusCode().is4xxClientError()) {
                         // ...
                     }
                     // ...
                    clientResponse.bodyToMono(ExampleResponse.class);
}); 
1reaction
spring-projects-issuescommented, Jan 11, 2019

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 to onStatus that builds a Mono instead of a Throwable. The purpose of that Mono is to hold the Throwable. The new signature can look like this:

ResponseSpec onStatus(Predicate<HttpStatus> statusPredicate, Function<ClientResponse, Mono<?> exceptionFunction);

With the above method in place, application code could do something like the following:

Mono<ExampleResponse> exampleResponse = webClient.get()
                .uri("http://spring.io/example")
                .retrieve()
                .onStatus(HttpStatus.NOT_FOUND::equals,
                        clientResponse -> new CustomException("Not Found"))
                .onStatus(HttpStatus::isError,
                        clientResponse -> clientResponse.bodyToMono(ServiceException.class)
                                    .flatMap(serviceException - > Mono.error(serviceException)))
                .bodyToMono(ExampleResponse.class);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring Web Client Exception Handling | by David - Medium
Exception handling in Spring's new WebClient with custom and unforeseen exceptions. This article assumes you have at least a little ...
Read more >
Handling Errors in Spring WebFlux - Baeldung
Customize the Global Error Response Attributes; Implement the Global Error Handler. The exception that our handler throws will be automatically ...
Read more >
Handling errors from Spring WebClient in another method
A reactive solution would be to use the onErrorResume operator like this: webClient.post() .uri("http://localhost:9000/api") .body(BodyInserters ...
Read more >
Spring WebClient 句柄404, Spring WebClient 异常处理, Spring ...
RELEASE , Convenience API for custom error handling on WebClient [SPR-15724] #20280。已关闭。spring-issuemaster 于2017 年7 月1 日打开此问题· 20 条评论。
Read more >
Error Handling for REST with Spring
Guide to implement a Global Exception Handler for a REST API with Spring. learn how to implement spring REST exception handling.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found