Spring RestTemplate - Overriding ResponseErrorHandler

rest, resttemplate, spring, spring-mvc

Solution

Following link has useful information about Exception Flow for Spring ResponseErrorHandler .

Adding code here, just in-case the blog is down:

Code for ErrorHandler:

public class MyResponseErrorHandler implements ResponseErrorHandler {

    private static final Log logger = LogFactory.getLog(MyResponseErrorHandler.class);

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

        if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
            logger.debug(HttpStatus.FORBIDDEN + " response. Throwing authentication exception");
            throw new AuthenticationException();
        }
    }

    @Override
    public boolean hasError(ClientHttpResponse clienthttpresponse) throws IOException {

        if (clienthttpresponse.getStatusCode() != HttpStatus.OK) {
            logger.debug("Status code: " + clienthttpresponse.getStatusCode());
            logger.debug("Response" + clienthttpresponse.getStatusText());
            logger.debug(clienthttpresponse.getBody());

            if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
                logger.debug("Call returned a error 403 forbidden resposne ");
                return true;
            }
        }
        return false;
    }
}

Code for using it in RestTemplate:

RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new MyResponseErrorHandler());
ResponseEntity<String> responseEntity = clientRestTemplate.exchange(
                    URI,
                    HttpMethod.GET,
                    requestEntity,
                    String.class);
                response = responseEntity.getBody();

Problem

I am calling a `ReST` service through `RestTemplate` and trying to override `ResponseErrorHandler` in `Spring 3.2` to handle custom error codes. CustomResponseErrroHandler ``` public class MyResponseErrorHandler implements ResponseErrorHandler { @Override public boolean hasError(ClientHttpResponse response) throws IOException { boolean hasError = false; int rawStatusCode = response.getRawStatusCode(); if (rawStatusCode != 200){ hasError = true; } return hasError; } @Override public void handleError(ClientHttpResponse response) throws IOException { //String body = IOUtils.toString(response.getBody()); throw new CustomServiceException(response.getRawStatusCode() , "custom Error"); } } ``` `Spring` framework invokes `hasError` method but not `handleError`, so I couldn't throw my custom exception. After delving into `Spring` `RestTemplate` source code, I realized that the code in `handleResponseError` method is causing the issue - It is looking for `response.getStatusCode` or `response.getStatusText` and throwing exception (as statusCode/statusText is null when `Rest` service throws exception) and it never calls either custom implemented or default `handleError` method in the next line. `Spring` `RestTemplate` source code for `handleResponse` method: ``` private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException { if (logger.isWarnEnabled()) { try { logger.warn(method.name() + " request for \"" + url + "\" resulted in " + response.getStatusCode() + " (" + response.getStatusText() + "); invoking error handler"); } catch (IOException e) { // ignore } } getErrorHandler().handleError(response); } ``` FYI, while service throws exception, I can read rawstatuscode but not statuscode from response How to bypass this framework code and make call my custom handler? Thanks for your help in advance.

Original source

Related problems