Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot how to ignore HttpStatus Exceptions

I'm building an Application using Spring Boot. This application is distributed, which means I have multiple API's that call each others.

One of my underlying services interacts with a database and responds with the requested data. If a request to an unexisting ID is made, I response with a 404 HttpStatus:

return new ResponseEntity<>(HttpStatus.NOT_FOUND);

(Same with 400 error on certain operations, or 204 for deleting an entry etc).

The problem is that I have some other Spring Boot applications that call these API's, throw an org.springframework.web.client.HttpClientErrorException: 404 Not Found Exception when they request, in this example, an unexisting entry. But the 404 status code is intended and should not return this exception (causing my Hystrix circuit breaker to call its fallback function).

How can I solve this problem?

The call to the service is implemented like this in my code: ResponseEntity<Object> data = restTemplate.getForEntity(url, Object.class);

My RestTemplate is set up like this:

private RestTemplate restTemplate = new RestTemplate();
like image 729
Kaj Avatar asked Sep 30 '15 14:09

Kaj


1 Answers

Spring's RestTemplate uses a ResponseErrorHandler to handle errors in responses. This interface provides both a way to determine if the response has an error (ResponseErrorHandler#hasError(ClientHttpResponse)) and how to handle it (ResponseErrorHandler#handleError(ClientHttpResponse)).

You can set the RestTemplate's ResponseErrorHandler with RestTemplate#setErrorHandler(ResponseErrorHandler) whose javadoc states

By default, RestTemplate uses a DefaultResponseErrorHandler.

This default implementation

[...] checks for the status code on the ClientHttpResponse: any code with series HttpStatus.Series.CLIENT_ERROR or HttpStatus.Series.SERVER_ERROR is considered to be an error. This behavior can be changed by overriding the hasError(HttpStatus) method.

In case of an error, it throws the exception you are seeing.

If you want to change this behavior, you can provide your own ResponseErrorHandler implementation (maybe by overriding DefaultResponseErrorHandler) which doesn't consider 4xx as an error or that doesn't throw an exception.

For example

restTemplate.setErrorHandler(new ResponseErrorHandler() {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return false; // or whatever you consider an error
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        // do nothing, or something
    }
});

You can then check the status code of the ResponseEntity returned by getForEntity and handle it yourself.

like image 77
Sotirios Delimanolis Avatar answered Oct 29 '22 05:10

Sotirios Delimanolis