Ensure client response is drained with onStatus hook

Issue: SPR-17473
This commit is contained in:
Rossen Stoyanchev
2018-11-08 13:26:41 -05:00
parent 8a2262e210
commit f73a5222f1
6 changed files with 216 additions and 25 deletions

View File

@@ -433,12 +433,22 @@ class DefaultWebClient implements WebClient {
private <T extends Publisher<?>> T bodyToPublisher(ClientResponse response,
T bodyPublisher, Function<Mono<? extends Throwable>, T> errorFunction) {
return this.statusHandlers.stream()
.filter(statusHandler -> statusHandler.test(response.statusCode()))
.findFirst()
.map(statusHandler -> statusHandler.apply(response))
.map(errorFunction::apply)
.orElse(bodyPublisher);
for (StatusHandler handler : this.statusHandlers) {
if (handler.test(response.statusCode())) {
Mono<? extends Throwable> exMono = handler.apply(response);
exMono = exMono.flatMap(ex -> drainBody(response, ex));
exMono = exMono.onErrorResume(ex -> drainBody(response, ex));
return errorFunction.apply(exMono);
}
}
return bodyPublisher;
}
@SuppressWarnings("unchecked")
private <T> Mono<T> drainBody(ClientResponse response, Throwable ex) {
// Ensure the body is drained, even if the StatusHandler didn't consume it,
// but ignore errors in case it did consume it.
return (Mono<T>) response.bodyToMono(Void.class).onErrorMap(ex2 -> ex).thenReturn(ex);
}
private static Mono<WebClientResponseException> createResponseException(ClientResponse response) {

View File

@@ -596,6 +596,9 @@ public interface WebClient {
* {@link WebClientResponseException} when the response status code is 4xx or 5xx.
* @param statusPredicate a predicate that indicates whether {@code exceptionFunction}
* applies
* <p><strong>NOTE:</strong> if the response is expected to have content,
* the exceptionFunction should consume it. If not, the content will be
* automatically drained to ensure resources are released.
* @param exceptionFunction the function that returns the exception
* @return this builder
*/