In an earlier article, I wrote about making HTTP requests using the RestTemplate class in a Spring Boot application.

In this short article, you'll learn how to handle the errors thrown by the RestTemplate, during the execution of an HTTP request.

Default error handling

By default, if there is an error during the execution of the request or the server returns a non-successful HTTP status code (4xx or 5xx), RestTemplate will throw one of the following exceptions:

  • HttpClientErrorException — For HTTP status code 4xx
  • HttpServerErrorException — For HTTP status code 5xx
  • UnknownHttpStatusCodeException — In case of an unknown HTTP status code

All these exceptions extend a base class called RestClientResponseException that contains actual HTTP response data.

Error handling using try...catch

The simplest way to add a custom error handler is to use a try-catch block to catch the HttpStatusCodeException exception. From the HttpStatusCodeException instance, you can then get the response status code, body, and headers, as shown below:

try {
    // request url
    String url = "https://reqres.in/api/unknown/23";

    // create an instance of RestTemplate
    RestTemplate restTemplate = new RestTemplate();

    // make an HTTP GET request
    ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
    
} catch (HttpStatusCodeException ex) {
    // raw http status code e.g `404`
    System.out.println(ex.getRawStatusCode());
    
    // http status code e.g. `404 NOT_FOUND`
    System.out.println(ex.getStatusCode().toString());
    
    // get response body
    System.out.println(ex.getResponseBodyAsString());
    
    // get http headers
    HttpHeaders headers = ex.getResponseHeaders();
    System.out.println(headers.get("Content-Type"));
    System.out.println(headers.get("Server"));
}

Implementing a custom error handler

Sometimes, a try-catch block is not enough to handle errors as it is not scalable when the number of HTTP requests increases.

You may want to create a reusable custom error handler by implementing the ResponseErrorHandler interface as follows:

MyErrorHandler.java

package com.attacomsian.runner;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.ResponseErrorHandler;

import java.io.IOException;

public class MyErrorHandler implements ResponseErrorHandler {

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return new DefaultResponseErrorHandler().hasError(response);
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {

        if (response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
            // handle 5xx errors
            // raw http status code e.g `500`
            System.out.println(response.getRawStatusCode());

            // http status code e.g. `500 INTERNAL_SERVER_ERROR`
            System.out.println(response.getStatusCode());

        } else if (response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
            // handle 4xx errors
            // raw http status code e.g `404`
            System.out.println(response.getRawStatusCode());

            // http status code e.g. `404 NOT_FOUND`
            System.out.println(response.getStatusCode());

            // get response body
            System.out.println(response.getBody());

            // get http headers
            HttpHeaders headers = response.getHeaders();
            System.out.println(headers.get("Content-Type"));
            System.out.println(headers.get("Server"));
        }
    }
}

You can now create an instance of MyErrorHandler and pass it to the RestTemplate class:

// request url
String url = "https://reqres.in/api/unknown/23";

// create an instance of RestTemplate
RestTemplate restTemplate = new RestTemplate();

// set custom error handler
restTemplate.setErrorHandler(new MyErrorHandler());

// make an HTTP GET request
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

Check out the Making HTTP Requests using RestTemplate in Spring Boot guide for more RestTemplate examples.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.