Friday 15 February 2019

How to handle error messages from HTTP response using Spring Boot Rest Template.


When a Rest endpoint is called using RestTemplate ,RestTemplate internals will consume the response and it will throw one of the below exception to the calling code based on the response status code it receives .

Below are the two basic exception classes thrown by RestTemplate.

HttpServerErrorException
HttpClientErrorException

Example :

        ResponseEntity responseEntity = restTemplate.postForEntity("/profile/create", entity, String.class);


But how does it know when to create an exception of the above type.

Below are the various scenarios from controller methods.

Case 1 :

Controller received the input. Processed the input .

Server method throws an exception (something like throw new Exception(),throw new  RuntimeException())
 
if(request.getId()==null){
throw WrongDataException("I think you sent wrong data");
 }

 This can be caught in the caller code using HttpServerErrorException .

Remember:  When you throw an exception directly,the HTTP status response sent to client is 500,unless otherwise the exception class being thrown has @ResponseStatus marked like below

 Example:

throw new WrongDataException("I think you sent wrong data");
        @ResponseStatus(value=HttpStatus.NOT_FOUND)
  public class WrongDataException(){
}


Case 2 :

Controller received the input. Processed the input .

if(request.getId()!=someValue){
     return new ResponseEntity("I think you sent wrong data", HttpStatus.NOT_FOUND);
}

still RestTemplate create an exception of type :  HttpClientErrorException .

So Basically

5XX - > HttpServerErrorException
4XX - > HttpClientErrorException

However you can catch all of the above with the base Exception class,but may not able to extract the message you embed inside the ResponseEntity. The message you set in ResponseEntity or in Exception constructor can be consumed only throw below way

catch(HttpServerErrorException e){
    LOGGER.error("error with StatusCode {} , Message {} ",
                                                                   e.getStatusCode(),
                                                                   e.getResponseBodyAsString());
}

If you ever want to get the response message body then you must catch these exception types.

NOTE : RestTemplate does not create any exception if the response status code is 2XX.


Let me know for any feedback/inputs.