I am calling an external API from my code using RestTemplate like below:
try { responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, UploadResonse.class); } catch (BusinessException ex) { fetchErrorResponseEntity = ex.getResponseEntity(); if (fetchErrorResponseEntity.getStatusCodeValue() == 404) { throw new BusinessException(ex.getMessage(), ErrorResponse.NOT_FOUND); } else if (fetchErrorResponseEntity.getStatusCodeValue() == 500) { throw new BusinessException(ex.getMessage(), ErrorResponse.INTERNAL_SERVER_ERROR); } else if (fetchErrorResponseEntity.getStatusCodeValue() == 400) { throw new BusinessException(ex.getMessage(), ErrorResponse.INVALID_REQUEST); } }
This API call is returning 200 Success but when I debug it, it still goes to handleResponse(URI url, HttpMethod method, ClientHttpResponse response) method of RestTemplate.class
And then it’s coming to my RestTemplateErrorHandler.java file
@Override public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { return clientHttpResponse.getStatusCode() != HttpStatus.OK; } @Override public void handleError(ClientHttpResponse clientHttpResponse) throws IOException { String errMessage = getErrMessage(clientHttpResponse); HttpStatus status = clientHttpResponse.getStatusCode(); switch (status) { case BAD_REQUEST: // 400 throw new BusinessException(errMessage, ErrorResponse.INVALID_REQUEST); case NOT_FOUND: throw new BusinessException(errMessage, ErrorResponse.NOT_FOUND); case SERVICE_UNAVAILABLE: // 503 throw new BusinessException(errMessage, ErrorResponse.TIME_OUT); case METHOD_NOT_ALLOWED: // 405 case INTERNAL_SERVER_ERROR: // 500 default: throw new BusinessException(errMessage, ErrorResponse.INTERNAL_SERVER_ERROR); } }
Can someone lease help me to understand if it’s the correct behaviour. I suspect that if the response is 200 Success it should not go to the RestTemlate.class and RestTemplateErrorHandler.class This behaviour is creating problem when API return 201 Created status, that time it goes to handleError() method and return the default case INTERNAL_SERVER_ERROR Can someone please help me here
Advertisement
Answer
The following code will call the error handler every time the response is not 200 OK, event if it is successful like 201 Created.
@Override public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { return clientHttpResponse.getStatusCode() != HttpStatus.OK; }
Try changing the implementation to the following:
@Override public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { return !clientHttpResponse.getStatusCode().is2xxSuccessful(); }
This is better suited for your needs as it will consider all 2xx status as successful requests instead of only 200 OK.