Spring Boot: How to handle RestTemplate exceptions
Handling exceptions coming from your RestTemplate instances is important because they are subclasses of RuntimeException so if you don’t catch them they will be thrown up to your top layer (let’s say a @RestController layer).
To handle those exceptions you can catch them in a @ControllerAdvice error handler.
Here is a way to handle RestTemplate exceptions, in this example the application have multiple RestTemplate instances that calls different APIs.
List the APIs you call in an enum
First let’s define an enum that will list all the downstream APIs you will call using RestTemplate.
This enumeration will be used for logging purposes, so that when you catch an exception you can log (or do whatever you want) that an error happened when calling that downstream API.
Custom RestTemplate error handling
When using a RestTemplate, the default error handling will throw an exception when the call returned a HTTP 4xx or HTTP 5xx.
The goal here is to convert each HTTP 4xx and HTTP 5xx to a custom RuntimeException.
This custom exception will hold information about the downstream API, the HTTP response status and an error message.
Here is the code that will catch every HTTP 4xx and 5xx errors thrown by RestTemplate when calling the API “MY_API1”.
You should create a custom error handler per API so you can handle them in a different way (for example if they have different error responses you can parse it here and provide more information in your “global” exception MyRestTemplateException.java).
DAO
The DAO will make the REST call by using RestTemplate. The RestTemplate instance is created in a way it is using the custom RestTemplate Error Handler we defined earlier.
Controller advice
Once you have converted the RestTemplate exceptions to MyRestTemplateException, you have to catch them in a global Exception Handler and convert it to a “generic” error response (here ErrorResponse.java)
Here is the “generic” error response POJO:
Then defined the error handler in a @ControllerAdvice class and you are good to go!
Controller layer
Sample of error returned
Here is the error response that would be returned when calling POST /update-stuff if the downstream API “MY_API1” throws an error: