/** * Responsible for handling an error response, including unmarshalling the error response into the * most specific exception type possible, and throwing the exception. * * @param request The request that generated the error response being handled. * @param errorResponseHandler The response handler responsible for unmarshalling the error * response. * @param method The HTTP method containing the actual response content. * @throws IOException If any problems are encountering reading the error response. */ private AmazonServiceException handleErrorResponse( Request<?> request, HttpResponseHandler<AmazonServiceException> errorResponseHandler, HttpRequestBase method, org.apache.http.HttpResponse apacheHttpResponse) throws IOException { int status = apacheHttpResponse.getStatusLine().getStatusCode(); HttpResponse response = createResponse(method, request, apacheHttpResponse); if (errorResponseHandler.needsConnectionLeftOpen() && method instanceof HttpEntityEnclosingRequestBase) { HttpEntityEnclosingRequestBase entityEnclosingRequest = (HttpEntityEnclosingRequestBase) method; response.setContent(new HttpMethodReleaseInputStream(entityEnclosingRequest)); } AmazonServiceException exception = null; try { exception = errorResponseHandler.handle(response); requestLog.debug("Received error response: " + exception.toString()); } catch (Exception e) { // If the errorResponseHandler doesn't work, then check for error // responses that don't have any content if (status == 413) { exception = new AmazonServiceException("Request entity too large"); exception.setServiceName(request.getServiceName()); exception.setStatusCode(413); exception.setErrorType(ErrorType.Client); exception.setErrorCode("Request entity too large"); } else if (status == 503 && "Service Unavailable" .equalsIgnoreCase(apacheHttpResponse.getStatusLine().getReasonPhrase())) { exception = new AmazonServiceException("Service unavailable"); exception.setServiceName(request.getServiceName()); exception.setStatusCode(503); exception.setErrorType(ErrorType.Service); exception.setErrorCode("Service unavailable"); } else if (e instanceof IOException) { throw (IOException) e; } else { String errorMessage = "Unable to unmarshall error response (" + e.getMessage() + "). Response Code: " + status + ", Response Text: " + apacheHttpResponse.getStatusLine().getReasonPhrase(); throw new AmazonClientException(errorMessage, e); } } exception.setStatusCode(status); exception.setServiceName(request.getServiceName()); exception.fillInStackTrace(); return exception; }
@Override public AmazonServiceException handle(HttpResponse response) throws Exception { JsonErrorResponse error; try { error = JsonErrorResponse.fromResponse(response); } catch (IOException e) { throw new AmazonClientException("Unable to parse error response", e); } AmazonServiceException ase = runErrorUnmarshallers(error); if (ase == null) return null; ase.setStatusCode(response.getStatusCode()); if (response.getStatusCode() < 500) { ase.setErrorType(ErrorType.Client); } else { ase.setErrorType(ErrorType.Service); } ase.setErrorCode(error.getErrorCode()); for (Entry<String, String> headerEntry : response.getHeaders().entrySet()) { if (headerEntry.getKey().equalsIgnoreCase("X-Amzn-RequestId")) { ase.setRequestId(headerEntry.getValue()); } } return ase; }
@Override public AmazonServiceException handle(com.amazonaws.http.HttpResponse response) throws Exception { AmazonServiceException ase = new AmazonServiceException("Fake service exception."); ase.setStatusCode(response.getStatusCode()); ase.setErrorCode(response.getStatusText()); return ase; }
@Test @SuppressWarnings("unchecked") public void testDoWithRetry_ThrottleException() throws Exception { AmazonElasticMapReduceCustomClient client = new AmazonElasticMapReduceCustomClient("dummy", "dummy"); client.setRequestInterval(100); Callable callable = mock(Callable.class); AmazonServiceException exception = new AmazonServiceException("Rate exceeded"); exception.setErrorCode("Throttling"); exception.setStatusCode(400); when(callable.call()).thenThrow(exception, exception, exception).thenReturn(new Object()); long startTime = System.currentTimeMillis(); Object result = client.doThrottleSafe(callable); assertNotNull(result); assertThat( (System.currentTimeMillis() - startTime), greaterThanOrEqualTo(3 * client.getRequestInterval())); }