RestTemplate throws RestClientResponseException subtypes such as HttpClientErrorException, HttpServerErrorException and UnknownHttpStatusCodeException separately if the response HTTP status code is 4xx, 5xx and unknown
You can handle RestTemplate errors at the local level by catching the RestClientResponseException, at the bean level by implementing the ResponseErrorHandler interface and plugging into a RestTemplate bean
Let's walk through this tutorial to explore them in more detail examples
The RestClientResponseException
RestClientResponseException is a common base class for exceptions that contain actual HTTP response data
You can use getRawStatusCode, getStatusText, getResponseHeaders, getResponseBodyAsString to get HTTP status code in integer number, get HTTP response headers, and get HTTP response body as a String. They are useful when you need to log and return detail error to the client
Catch RestClientResponseException
RestTemplate can only return a ResponseEntity with HTTP 2xx status. With 4xx and 5xx status, RestTemplate throws HttpClientErrorException and HttpServerErrorException which are extended from HttpStatusCodeException and RestClientResponseException hierarchically
<T> ResponseEntity consumeWebService(String url, Class<T> responseType) {
try {
return restTemplate.getForEntity(url, responseType);
} catch (RestClientResponseException e) {
return ResponseEntity
.status(e.getRawStatusCode())
.body(e.getResponseBodyAsString());
}
}
Beside catching RestClientResponseException, you can also catch HttpStatusCodeException
The following gives you an integration test example with MockRestServiceServer
Implement ResponseErrorHandler
If you don't like try-catch every time executing a RestTemplate request, try to implement ResponseErrorHandler and add it to the RestTemplate bean
hasError method is used to indicate whether the given response has any errors
The two handleError methods are used to handle the error in the given response. Only handleError(response) is required to implement, however, it will be overshadowed if you implement handleError(URI url, HttpMethod method, ClientHttpResponse response)
Plug your custom ResponseErrorHandler into a RestTemplate bean
To make your custom ResponseErrorHandler work, you have to register it with a RestTemplate bean
In practice, to follow DRY and leverage the Spring Dependency Injection, you can define your RestTemplate beans in a separate class config and inject it via @Autowired into where it is used such as Spring @Component or @Service class
The following gives you an integration test example with SpringRunner and MockRestServiceServer
Conclusion
In this tutorial, we learned to handle RestTemplate error by catching RestClientResponseException and implementing ResponseErrorHandler. You can find the full source code on GitHub