Skip to content

Commit 134bb6e

Browse files
committed
Document exception wrapping in RestClient status handlers
This commit documents the fact that any (Unchecked)IOExceptions or HttpMessageNotReadableExceptions thrown from the error handler will be wrapped in a RestClientException. Closes gh-31783
1 parent 240a75f commit 134bb6e

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,15 @@ private <T> T readWithMessageConverters(ClientHttpResponse clientResponse, Runna
220220
responseWrapper.getHeaders(), RestClientUtils.getBody(responseWrapper));
221221
}
222222
catch (UncheckedIOException | IOException | HttpMessageNotReadableException ex) {
223+
Throwable cause;
224+
if (ex instanceof UncheckedIOException uncheckedIOException) {
225+
cause = uncheckedIOException.getCause();
226+
}
227+
else {
228+
cause = ex;
229+
}
223230
throw new RestClientException("Error while extracting response for type [" +
224-
ResolvableType.forType(bodyType) + "] and content type [" + contentType + "]", ex);
231+
ResolvableType.forType(bodyType) + "] and content type [" + contentType + "]", cause);
225232
}
226233
}
227234

spring-web/src/main/java/org/springframework/web/client/RestClient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,11 @@ interface ResponseSpec {
705705
* Provide a function to map specific error status codes to an error handler.
706706
* <p>By default, if there are no matching status handlers, responses with
707707
* status codes &gt;= 400 wil throw a {@link RestClientResponseException}.
708+
* <p>Note that {@link IOException IOExceptions},
709+
* {@link java.io.UncheckedIOException UncheckedIOExceptions}, and
710+
* {@link org.springframework.http.converter.HttpMessageNotReadableException HttpMessageNotReadableExceptions}
711+
* thrown from {@code errorHandler} will be wrapped in a
712+
* {@link RestClientException}.
708713
* @param statusPredicate to match responses with
709714
* @param errorHandler handler that typically, though not necessarily,
710715
* throws an exception
@@ -717,6 +722,11 @@ ResponseSpec onStatus(Predicate<HttpStatusCode> statusPredicate,
717722
* Provide a function to map specific error status codes to an error handler.
718723
* <p>By default, if there are no matching status handlers, responses with
719724
* status codes &gt;= 400 wil throw a {@link RestClientResponseException}.
725+
* <p>Note that {@link IOException IOExceptions},
726+
* {@link java.io.UncheckedIOException UncheckedIOExceptions}, and
727+
* {@link org.springframework.http.converter.HttpMessageNotReadableException HttpMessageNotReadableExceptions}
728+
* thrown from {@code errorHandler} will be wrapped in a
729+
* {@link RestClientException}.
720730
* @param errorHandler the error handler
721731
* @return this builder
722732
*/

spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,27 @@ void statusHandler(ClientHttpRequestFactory requestFactory) {
592592
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
593593
}
594594

595+
@ParameterizedRestClientTest
596+
void statusHandlerIOException(ClientHttpRequestFactory requestFactory) {
597+
startServer(requestFactory);
598+
599+
prepareResponse(response -> response.setResponseCode(500)
600+
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
601+
602+
assertThatExceptionOfType(RestClientException.class).isThrownBy(() ->
603+
this.restClient.get()
604+
.uri("/greeting")
605+
.retrieve()
606+
.onStatus(HttpStatusCode::is5xxServerError, (request, response) -> {
607+
throw new IOException("500 error!");
608+
})
609+
.body(String.class)
610+
).withCauseInstanceOf(IOException.class);
611+
612+
expectRequestCount(1);
613+
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
614+
}
615+
595616
@ParameterizedRestClientTest
596617
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
597618
startServer(requestFactory);

0 commit comments

Comments
 (0)