diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandler.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandler.java
index d2b96d8e2..cf2aae3e7 100644
--- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandler.java
+++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandler.java
@@ -22,6 +22,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
@@ -31,7 +32,8 @@
/**
* Default implementation of the ExceptionHandler
object that returns AwsProxyResponse objects.
*
- * Returns application/json messages with a status code of 500 when the RequestReader failed to read the incoming event.
+ * Returns application/json messages with a status code of 500 when the RequestReader failed to read the incoming event
+ * or if InternalServerErrorException is thrown.
* For all other exceptions returns a 502. Responses are populated with a JSON object containing a message property.
*
* @see ExceptionHandler
@@ -76,7 +78,7 @@ public AwsProxyResponse handle(Throwable ex) {
// adding a print stack trace in case we have no appender or we are running inside SAM local, where need the
// output to go to the stderr.
ex.printStackTrace();
- if (ex instanceof InvalidRequestEventException) {
+ if (ex instanceof InvalidRequestEventException || ex instanceof InternalServerErrorException) {
return new AwsProxyResponse(500, headers, getErrorJson(INTERNAL_SERVER_ERROR));
} else {
return new AwsProxyResponse(502, headers, getErrorJson(GATEWAY_TIMEOUT_ERROR));
diff --git a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandlerTest.java b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandlerTest.java
index b5ed6f77a..cf86c57a6 100644
--- a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandlerTest.java
+++ b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/AwsProxyExceptionHandlerTest.java
@@ -3,7 +3,6 @@
import com.amazonaws.serverless.exceptions.InvalidRequestEventException;
import com.amazonaws.serverless.exceptions.InvalidResponseObjectException;
-import com.amazonaws.serverless.proxy.AwsProxyExceptionHandler;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.model.ErrorModel;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -16,18 +15,22 @@
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
+import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.*;
public class AwsProxyExceptionHandlerTest {
+ private static final String INTERNAL_SERVER_ERROR_MESSAGE = "Internal server error";
private static final String INVALID_REQUEST_MESSAGE = "Invalid request error";
private static final String INVALID_RESPONSE_MESSAGE = "Invalid response error";
private AwsProxyExceptionHandler exceptionHandler;
private ObjectMapper objectMapper;
+
@Before
public void setUp() {
exceptionHandler = new AwsProxyExceptionHandler();
@@ -88,6 +91,44 @@ public void typedHandle_InvalidResponseObjectException_jsonContentTypeHeader() {
assertEquals(MediaType.APPLICATION_JSON, resp.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE));
}
+ @Test
+ public void typedHandle_InternalServerErrorException_500State() {
+ // Needed to mock InternalServerErrorException because it leverages RuntimeDelegate to set an internal
+ // response object.
+ InternalServerErrorException mockInternalServerErrorException = Mockito.mock(InternalServerErrorException.class);
+ Mockito.when(mockInternalServerErrorException.getMessage()).thenReturn(INTERNAL_SERVER_ERROR_MESSAGE);
+
+ AwsProxyResponse resp = exceptionHandler.handle(mockInternalServerErrorException);
+
+ assertNotNull(resp);
+ assertEquals(500, resp.getStatusCode());
+ }
+
+ @Test
+ public void typedHandle_InternalServerErrorException_responseString()
+ throws JsonProcessingException {
+ InternalServerErrorException mockInternalServerErrorException = Mockito.mock(InternalServerErrorException.class);
+ Mockito.when(mockInternalServerErrorException.getMessage()).thenReturn(INTERNAL_SERVER_ERROR_MESSAGE);
+
+ AwsProxyResponse resp = exceptionHandler.handle(mockInternalServerErrorException);
+
+ assertNotNull(resp);
+ String body = objectMapper.writeValueAsString(new ErrorModel(AwsProxyExceptionHandler.INTERNAL_SERVER_ERROR));
+ assertEquals(body, resp.getBody());
+ }
+
+ @Test
+ public void typedHandle_InternalServerErrorException_jsonContentTypeHeader() {
+ InternalServerErrorException mockInternalServerErrorException = Mockito.mock(InternalServerErrorException.class);
+ Mockito.when(mockInternalServerErrorException.getMessage()).thenReturn(INTERNAL_SERVER_ERROR_MESSAGE);
+
+ AwsProxyResponse resp = exceptionHandler.handle(mockInternalServerErrorException);
+
+ assertNotNull(resp);
+ assertTrue(resp.getMultiValueHeaders().containsKey(HttpHeaders.CONTENT_TYPE));
+ assertEquals(MediaType.APPLICATION_JSON, resp.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE));
+ }
+
@Test
public void typedHandle_NullPointerException_responseObject()
throws JsonProcessingException {
diff --git a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyServletResponseWriter.java b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyServletResponseWriter.java
index c2cba7319..938c6f9ff 100644
--- a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyServletResponseWriter.java
+++ b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyServletResponseWriter.java
@@ -122,14 +122,8 @@ public void commit() {
public void failure(Throwable throwable) {
- try {
- log.error("failure", throwable);
- jerseyLatch.countDown();
- servletResponse.flushBuffer();
- } catch (IOException e) {
- log.error("Could not fail response", e);
- throw new InternalServerErrorException(e);
- }
+ log.error("failure", throwable);
+ throw new InternalServerErrorException("Jersey failed to process request", throwable);
}
diff --git a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/EchoJerseyResource.java b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/EchoJerseyResource.java
index da67dcf36..ec0f4b2ac 100644
--- a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/EchoJerseyResource.java
+++ b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/EchoJerseyResource.java
@@ -24,6 +24,7 @@
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.FormDataParam;
+import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -59,6 +60,9 @@ public class EchoJerseyResource {
@Context
SecurityContext securityCtx;
+ @Inject
+ JerseyDependency jerseyDependency;
+
@Path("/decoded-param") @GET
@Produces(MediaType.APPLICATION_JSON)
public SingleValueModel echoDecodedParam(@QueryParam("param") String param) {
diff --git a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyTest.java b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyTest.java
index c54de6c5a..e791ae810 100644
--- a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyTest.java
+++ b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyTest.java
@@ -14,16 +14,15 @@
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
-import com.amazonaws.serverless.proxy.jersey.providers.ServletRequestFilter;
-import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
-import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.internal.servlet.AwsServletContext;
-import com.amazonaws.serverless.proxy.jersey.model.MapResponseModel;
-import com.amazonaws.serverless.proxy.jersey.model.SingleValueModel;
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
+import com.amazonaws.serverless.proxy.jersey.model.MapResponseModel;
+import com.amazonaws.serverless.proxy.jersey.model.SingleValueModel;
+import com.amazonaws.serverless.proxy.jersey.providers.ServletRequestFilter;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.services.lambda.runtime.Context;
-
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
@@ -37,13 +36,15 @@
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* Unit test class for the Jersey AWS_PROXY default implementation
@@ -57,13 +58,26 @@ public class JerseyAwsProxyTest {
private static ObjectMapper objectMapper = new ObjectMapper();
+
private static ResourceConfig app = new ResourceConfig().packages("com.amazonaws.serverless.proxy.jersey")
+ .register(LoggingFeature.class)
+ .register(ServletRequestFilter.class)
+ .register(MultiPartFeature.class)
+ .register(new ResourceBinder())
+ .property(LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER, LoggingFeature.Verbosity.PAYLOAD_ANY);
+
+ private static ResourceConfig appWithoutRegisteredDependencies = new ResourceConfig()
+ .packages("com.amazonaws.serverless.proxy.jersey")
.register(LoggingFeature.class)
.register(ServletRequestFilter.class)
.register(MultiPartFeature.class)
.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER, LoggingFeature.Verbosity.PAYLOAD_ANY);
+
private static JerseyLambdaContainerHandler handler = JerseyLambdaContainerHandler.getAwsProxyHandler(app);
+ private static JerseyLambdaContainerHandler handlerWithoutRegisteredDependencies
+ = JerseyLambdaContainerHandler.getAwsProxyHandler(appWithoutRegisteredDependencies);
+
private static Context lambdaContext = new MockLambdaContext();
private boolean isAlb;
@@ -76,15 +90,14 @@ public JerseyAwsProxyTest(boolean alb) {
public static Collection