Browse Source

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
pull/31837/head
Arjen Poutsma 2 years ago
parent
commit
134bb6e31f
  1. 9
      spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java
  2. 10
      spring-web/src/main/java/org/springframework/web/client/RestClient.java
  3. 21
      spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java

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

@ -220,8 +220,15 @@ final class DefaultRestClient implements RestClient { @@ -220,8 +220,15 @@ final class DefaultRestClient implements RestClient {
responseWrapper.getHeaders(), RestClientUtils.getBody(responseWrapper));
}
catch (UncheckedIOException | IOException | HttpMessageNotReadableException ex) {
Throwable cause;
if (ex instanceof UncheckedIOException uncheckedIOException) {
cause = uncheckedIOException.getCause();
}
else {
cause = ex;
}
throw new RestClientException("Error while extracting response for type [" +
ResolvableType.forType(bodyType) + "] and content type [" + contentType + "]", ex);
ResolvableType.forType(bodyType) + "] and content type [" + contentType + "]", cause);
}
}

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

@ -705,6 +705,11 @@ public interface RestClient { @@ -705,6 +705,11 @@ public interface RestClient {
* Provide a function to map specific error status codes to an error handler.
* <p>By default, if there are no matching status handlers, responses with
* status codes &gt;= 400 wil throw a {@link RestClientResponseException}.
* <p>Note that {@link IOException IOExceptions},
* {@link java.io.UncheckedIOException UncheckedIOExceptions}, and
* {@link org.springframework.http.converter.HttpMessageNotReadableException HttpMessageNotReadableExceptions}
* thrown from {@code errorHandler} will be wrapped in a
* {@link RestClientException}.
* @param statusPredicate to match responses with
* @param errorHandler handler that typically, though not necessarily,
* throws an exception
@ -717,6 +722,11 @@ public interface RestClient { @@ -717,6 +722,11 @@ public interface RestClient {
* Provide a function to map specific error status codes to an error handler.
* <p>By default, if there are no matching status handlers, responses with
* status codes &gt;= 400 wil throw a {@link RestClientResponseException}.
* <p>Note that {@link IOException IOExceptions},
* {@link java.io.UncheckedIOException UncheckedIOExceptions}, and
* {@link org.springframework.http.converter.HttpMessageNotReadableException HttpMessageNotReadableExceptions}
* thrown from {@code errorHandler} will be wrapped in a
* {@link RestClientException}.
* @param errorHandler the error handler
* @return this builder
*/

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

@ -592,6 +592,27 @@ class RestClientIntegrationTests { @@ -592,6 +592,27 @@ class RestClientIntegrationTests {
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerIOException(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
assertThatExceptionOfType(RestClientException.class).isThrownBy(() ->
this.restClient.get()
.uri("/greeting")
.retrieve()
.onStatus(HttpStatusCode::is5xxServerError, (request, response) -> {
throw new IOException("500 error!");
})
.body(String.class)
).withCauseInstanceOf(IOException.class);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);

Loading…
Cancel
Save