JsonErrorResponseHandler implements HttpResponseHandler<AmazonServiceException> { @Override public AmazonServiceException handle(HttpResponse response) throws Exception { JsonContent jsonContent = JsonContent.createJsonContent(response, jsonFactory); byte[] rawContent = jsonContent.getRawContent(); String errorCode = errorCodeParser.parseErrorCode(response, jsonContent); AmazonServiceException ase = createException(errorCode, response, jsonContent.getJsonNode(), rawContent); if (ase.getErrorMessage() == null) { ase.setErrorMessage(errorMessageParser.parseErrorMessage(response, jsonContent.getJsonNode())); } ase.setErrorCode(errorCode); ase.setServiceName(response.getRequest().getServiceName()); ase.setStatusCode(response.getStatusCode()); ase.setErrorType(getErrorTypeFromStatusCode(response.getStatusCode())); ase.setRawResponse(rawContent); String requestId = getRequestIdFromHeaders(response.getHeaders()); if (requestId != null) { ase.setRequestId(requestId); } ase.setHttpHeaders(response.getHeaders()); return ase; } JsonErrorResponseHandler(
            List<JsonErrorUnmarshaller> errorUnmarshallers,
            ErrorCodeParser errorCodeParser,
            JsonErrorMessageParser errorMessageParser,
            JsonFactory jsonFactory);  JsonErrorResponseHandler(
            List<JsonErrorUnmarshaller> errorUnmarshallers,
            Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> simpleTypeUnmarshallers,
            Map<JsonUnmarshallerContext.UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customTypeUnmarshallers,
            ErrorCodeParser errorCodeParser,
            JsonErrorMessageParser errorMessageParser,
            JsonFactory jsonFactory); @Override boolean needsConnectionLeftOpen(); @Override AmazonServiceException handle(HttpResponse response);  }
@Test public void handle_NoUnmarshallersAdded_ReturnsGenericAmazonServiceException() throws Exception { responseHandler = new JsonErrorResponseHandler(new ArrayList<JsonErrorUnmarshaller>(), new JsonErrorCodeParser(), JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER, new JsonFactory()); AmazonServiceException ase = responseHandler.handle(httpResponse); assertNotNull(ase); }
@Test public void handle_NoMatchingUnmarshallers_ReturnsGenericAmazonServiceException() throws Exception { expectUnmarshallerDoesNotMatch(); AmazonServiceException ase = responseHandler.handle(httpResponse); assertNotNull(ase); }
@Test public void handle_NullContent_ReturnsGenericAmazonServiceException() throws Exception { httpResponse.setStatusCode(500); httpResponse.setContent(null); AmazonServiceException ase = responseHandler.handle(httpResponse); assertEquals(ERROR_CODE, ase.getErrorCode()); assertEquals(500, ase.getStatusCode()); assertEquals(SERVICE_NAME, ase.getServiceName()); assertEquals(ErrorType.Service, ase.getErrorType()); }
@Test public void handle_EmptyContent_ReturnsGenericAmazonServiceException() throws Exception { httpResponse.setStatusCode(500); httpResponse.setContent(new StringInputStream("")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertNotNull(ase); }
@Test public void handle_UnmarshallerReturnsNull_ReturnsGenericAmazonServiceException() throws Exception { expectUnmarshallerMatches(); AmazonServiceException ase = responseHandler.handle(httpResponse); assertNotNull(ase); assertEquals(ERROR_CODE, ase.getErrorCode()); }
@Test public void handle_UnmarshallerThrowsException_ReturnsGenericAmazonServiceException() throws Exception { expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))).thenThrow(new RuntimeException()); AmazonServiceException ase = responseHandler.handle(httpResponse); assertNotNull(ase); assertEquals(ERROR_CODE, ase.getErrorCode()); }
@Test public void handle_UnmarshallerReturnsException_ClientErrorType() throws Exception { httpResponse.setStatusCode(400); expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertEquals(ERROR_CODE, ase.getErrorCode()); assertEquals(400, ase.getStatusCode()); assertEquals(SERVICE_NAME, ase.getServiceName()); assertEquals(ErrorType.Client, ase.getErrorType()); }
@Test public void handle_UnmarshallerReturnsException_ServiceErrorType() throws Exception { httpResponse.setStatusCode(500); expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertEquals(ErrorType.Service, ase.getErrorType()); }
@Test public void handle_UnmarshallerReturnsException_WithRequestId() throws Exception { httpResponse.setStatusCode(500); httpResponse.addHeader(HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER, "1234"); expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertEquals("1234", ase.getRequestId()); }
@Test public void handle_UnmarshallerReturnsException_WithCaseInsensitiveRequestId() throws Exception { httpResponse.setStatusCode(500); httpResponse.addHeader(StringUtils.upperCase(HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER), "1234"); expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertEquals("1234", ase.getRequestId()); }
@Test public void handle_UnmarshallerReturnsException_WithAlternativeRequestId() throws Exception { httpResponse.setStatusCode(500); httpResponse.addHeader(HttpResponseHandler.X_AMZ_REQUEST_ID_ALTERNATIVE_HEADER, "new1234"); expectUnmarshallerMatches(); when(unmarshaller.unmarshall((JsonNode) anyObject())) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertThat(ase.getHttpHeaders(), hasEntry(HttpResponseHandler.X_AMZ_REQUEST_ID_ALTERNATIVE_HEADER, "new1234")); }
@Test public void handle_AllHeaders_DumpedIntoHeaderMap() throws Exception { httpResponse.setStatusCode(500); httpResponse.addHeader("FooHeader", "FooValue"); httpResponse.addHeader(HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER, "1234"); expectUnmarshallerMatches(); when(unmarshaller.unmarshall(any(JsonNode.class))) .thenReturn(new CustomException("error")); AmazonServiceException ase = responseHandler.handle(httpResponse); assertThat(ase.getHttpHeaders(), hasEntry("FooHeader", "FooValue")); assertThat(ase.getHttpHeaders(), hasEntry(HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER, "1234")); }
@Test public void handle_unmarshallerIsEnhanced_usesUnmarshallFromContext() throws Exception { responseHandler = new JsonErrorResponseHandler(Arrays.<JsonErrorUnmarshaller>asList(enhancedUnmarshaller), simpleTypeUnmarshallers, customTypeUnmarshallers, errorCodeParser, JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER, new JsonFactory()); httpResponse.setStatusCode(400); expectUnmarshallerMatches(); responseHandler.handle(httpResponse); verify(enhancedUnmarshaller).unmarshallFromContext(any(JsonUnmarshallerContext.class)); }
@Test public void handle_unmarshallerIsEnhanced_jsonContextIsCorrect() throws Exception { responseHandler = new JsonErrorResponseHandler(Arrays.<JsonErrorUnmarshaller>asList(enhancedUnmarshaller), simpleTypeUnmarshallers, customTypeUnmarshallers, errorCodeParser, JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER, new JsonFactory()); String content = "{\"foo\":\"bar\"}"; httpResponse.setStatusCode(400); httpResponse.setContent(new ByteArrayInputStream(content.getBytes("UTF-8"))); expectUnmarshallerMatches(); ArgumentCaptor<JsonUnmarshallerContext> ctxCaptor = ArgumentCaptor.forClass(JsonUnmarshallerContext.class); responseHandler.handle(httpResponse); verify(enhancedUnmarshaller).unmarshallFromContext(ctxCaptor.capture()); JsonUnmarshallerContext capturedCtx = ctxCaptor.getValue(); capturedCtx.getUnmarshaller(String.class); capturedCtx.getUnmarshaller(String.class, JsonUnmarshallerContext.UnmarshallerType.JSON_VALUE); assertThat(capturedCtx.getJsonParser().readValueAsTree().toString(), equalTo(content)); assertThat(capturedCtx.getHttpResponse(), equalTo(httpResponse)); verify(simpleTypeUnmarshallers).get(eq(String.class)); verify(customTypeUnmarshallers).get(eq(JsonUnmarshallerContext.UnmarshallerType.JSON_VALUE)); }
@Test public void handle_unmarshallerIsEnhanced_contentIsMalformed_doesNotFail() throws Exception { responseHandler = new JsonErrorResponseHandler(Arrays.<JsonErrorUnmarshaller>asList(enhancedUnmarshaller), simpleTypeUnmarshallers, customTypeUnmarshallers, errorCodeParser, JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER, new JsonFactory()); String content = "This is not JSON"; httpResponse.setStatusCode(400); httpResponse.setContent(new ByteArrayInputStream(content.getBytes("UTF-8"))); expectUnmarshallerMatches(); final AmazonServiceException ase = new AmazonServiceException(null); when(enhancedUnmarshaller.unmarshallFromContext(any(JsonUnmarshallerContext.class))).thenAnswer(new Answer<AmazonServiceException>() { @Override public AmazonServiceException answer(InvocationOnMock invocationOnMock) throws Throwable { JsonUnmarshallerContext ctx = invocationOnMock.getArgumentAt(0, JsonUnmarshallerContext.class); while (ctx.nextToken() != null) { } return ase; } }); AmazonServiceException handledException = responseHandler.handle(httpResponse); assertThat(handledException, equalTo(ase)); }
@Test public void handle_unmarshallerIsLegacy_contentIsMalformed_doesNotFail() throws Exception { responseHandler = new JsonErrorResponseHandler(Arrays.<JsonErrorUnmarshaller>asList(unmarshaller), simpleTypeUnmarshallers, customTypeUnmarshallers, errorCodeParser, JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER, new JsonFactory()); String content = "This is not JSON"; httpResponse.setStatusCode(400); httpResponse.setContent(new ByteArrayInputStream(content.getBytes("UTF-8"))); expectUnmarshallerMatches(); final AmazonServiceException ase = new AmazonServiceException(null); when(unmarshaller.unmarshall(any(JsonNode.class))).thenAnswer(new Answer<AmazonServiceException>() { @Override public AmazonServiceException answer(InvocationOnMock invocationOnMock) throws Throwable { return ase; } }); AmazonServiceException handledException = responseHandler.handle(httpResponse); ArgumentCaptor<JsonNode> jsonNodeCaptor = ArgumentCaptor.forClass(JsonNode.class); verify(unmarshaller).unmarshall(jsonNodeCaptor.capture()); assertThat(jsonNodeCaptor.getValue().elements().hasNext(), is(false)); assertThat(handledException, equalTo(ase)); }