Title: WebClient - how to ignore a specific HTTP error
Tags: spring-webflux
Question: I'd like to create a Spring WebClient that ignores a specific HTTP error. From the documentation of WebClient.retrieve():
By default, 4xx and 5xx responses result in a WebClientResponseException. To customize error handling, use ResponseSpec.onStatus(Predicate, Function) handlers.
I want all calls through a WebClient instance to ignore the specific HTTP error. That is why onStatus() is of no use to me (it has to be set per response).
The best I could come up with is this:
WebClient webClient = WebClient.builder().filter((request, next) -&gt; {
Mono<ClientResponse&gt; response = next.exchange(request);
response = response.onErrorResume(WebClientResponseException.class, ex -&gt; {
return ex.getRawStatusCode() == 418 ? Mono.empty() : Mono.error(ex);
});
return response;
}).build();
URI uri = UriComponentsBuilder.fromUriString(&quot;https://httpstat.us/418&quot;).build().toUri();
webClient.get().uri(uri).retrieve().toBodilessEntity().block();
but it does throw the exception instead of ignoring it (the lambda passed to onErrorResume() is never called).
Edited: fixed the mistake pointed out by the first answer.


Here is another answer: After extensive debugging of spring-webflux 5.3.4 and with the help of some ideas by Martin Tarjányi, I've come to this as the only possible &quot;solution&quot;:
WebClient webClient = WebClient.builder().filter((request, next) -&gt; {
return next.exchange(request).flatMap(res -&gt; {
if (res.rawStatusCode() == HttpStatus.I_AM_A_TEAPOT.value()) {
res = res.mutate().rawStatusCode(299).build();
}
return Mono.just(res);
});
}).build();
URI uri = UriComponentsBuilder.fromUriString(&quot;https://httpstat.us/418&quot;).build().toUri();
String body = webClient.get().uri(uri).retrieve().toEntity(String.class).block().getBody();
The background: I am migrating some code from RestTemplate to WebClient. The old code looks like this:
RestTemplate restTemplate = ...;
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
if (response.getRawStatusCode() == HttpStatus.I_AM_A_TEAPOT.value()) {
return;
}
super.handleError(response);
URI uri = UriComponentsBuilder.fromUriString(&quot;https://httpstat.us/418&quot;).build().toUri();
String body = restTemplate.getForEntity(uri, String.class).getBody();
I believe it is a straightforward and common case.
WebClient is not yet a 100% replacement for RestTemplate.

Here is another answer: UPDATE: Turns out this answer doesn't address the core problem of filtering out a specific status code, just addresses a general coding pattern.
The reason onErrorResume lambda is not called is that response.onErrorResume creates a brand new Mono and your code does not use the result (i.e. it's not assigned to the response variable), so in the end a Mono without the onErrorResume operator is returned.
Using Project Reactor it's usually a good practice to avoid declaring local Mono and Flux variables and use a single chain instead. This helps to avoid similar subtle bugs.
WebClient webClient = WebClient.builder()
.filter((request, next) -&gt; next.exchange(request)
.onErrorResume(WebClientResponseException.class, ex -&gt; ex.getRawStatusCode() == 418 ? Mono.empty() : Mono.error(ex)))
.build();
Comment for this answer: It seems status codes are not errors at that point, so you should rather use `flatMap`: ```WebClient webClient = WebClient.builder()
.filter((request, next) -> next.exchange(request)
.flatMap(res -> res.rawStatusCode() == 416 ? Mono.empty() : Mono.just(res)))
.build();```
But this doesn't work either, because WebClient fails on empty `Mono`, so I don't see a solution for this. Sorry.
Comment for this answer: Thanks for pointing out my mistake.
However, even with your version of the code, the onErrorResume lambda is still not called and the exception gets thrown.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2021:00:03/05/21', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<spring-webflux>', 'Title': 'WebClient - how to ignore a specific HTTP error', 'ViewCount': 1485, 'id': 66498031, 'user_AboutMe': '', 'user_AccountId': 9767573.0, 'user_DisplayName': 'Gbr', 'user_Reputation': 53.0, 'user_Views': 10.0, 'user_id': 7240522.0}}