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 4xxHttpServerErrorException
— For HTTP status code 5xxUnknownHttpStatusCodeException
— 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.