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
This commit is contained in:
@@ -220,8 +220,15 @@ final class DefaultRestClient implements RestClient {
|
|||||||
responseWrapper.getHeaders(), RestClientUtils.getBody(responseWrapper));
|
responseWrapper.getHeaders(), RestClientUtils.getBody(responseWrapper));
|
||||||
}
|
}
|
||||||
catch (UncheckedIOException | IOException | HttpMessageNotReadableException ex) {
|
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 [" +
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -705,6 +705,11 @@ public interface RestClient {
|
|||||||
* Provide a function to map specific error status codes to an error handler.
|
* 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
|
* <p>By default, if there are no matching status handlers, responses with
|
||||||
* status codes >= 400 wil throw a {@link RestClientResponseException}.
|
* status codes >= 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 statusPredicate to match responses with
|
||||||
* @param errorHandler handler that typically, though not necessarily,
|
* @param errorHandler handler that typically, though not necessarily,
|
||||||
* throws an exception
|
* throws an exception
|
||||||
@@ -717,6 +722,11 @@ public interface RestClient {
|
|||||||
* Provide a function to map specific error status codes to an error handler.
|
* 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
|
* <p>By default, if there are no matching status handlers, responses with
|
||||||
* status codes >= 400 wil throw a {@link RestClientResponseException}.
|
* status codes >= 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
|
* @param errorHandler the error handler
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -592,6 +592,27 @@ class RestClientIntegrationTests {
|
|||||||
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
|
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
|
@ParameterizedRestClientTest
|
||||||
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
|
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
|
||||||
startServer(requestFactory);
|
startServer(requestFactory);
|
||||||
|
|||||||
Reference in New Issue
Block a user