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

Share to social

Van N.

Van N. is a software engineer, creator of HelloKoding. He loves coding, blogging, and traveling. You may find him on GitHub and LinkedIn