restore proper error dispatch test
package io.confluent.rest.metrics;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler;
import org.glassfish.jersey.server.ServerProperties;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import java.io.IOException;
import java.util.Properties;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import javax.ws.rs.ProcessingException;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Configurable;
@@ -20,12 +28,14 @@ import io.confluent.rest.RestConfig;
import io.confluent.rest.TestRestConfig;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class MetricsResourceMethodApplicationListenerIntegrationTest {
TestRestConfig config;
ApplicationWithFilter app;
+ volatile Throwable handledException = null;
@Before
public void setUp() throws Exception {
@@ -45,7 +55,7 @@ public class MetricsResourceMethodApplicationListenerIntegrationTest {
@Test
public void testListenerHandlesDispatchErrorsGracefully() {
// request events do not follow the typical order when an error is raised during dispatch
- // this test ensures we probably handle the case where we might encounter events in the
+ // this test ensures we properly handle the case where we might encounter events in the
// following order.
//
// MATCHING_START -> REQUEST_MATCHED -> REQUEST_FILTERED
@@ -58,9 +68,20 @@ public class MetricsResourceMethodApplicationListenerIntegrationTest {
.request(MediaType.APPLICATION_JSON_TYPE)
.get();
assertEquals(500, response.getStatus());
+ // ensure the true cause actually bubble up to the error handler
+ assertNotNull(handledException);
+ Throwable cause = handledException;
+ while (!(cause instanceof ProcessingException)) {
+ if (cause == cause.getCause()) {
+ break;
+ }
+ cause = cause.getCause();
+ }
+ assertTrue(cause instanceof ProcessingException);
+ assertEquals("Resource Java method invocation error.", cause.getMessage());
}
- private static class ApplicationWithFilter extends Application<TestRestConfig> {
+ private class ApplicationWithFilter extends Application<TestRestConfig> {
Configurable resourceConfig;
@@ -76,9 +97,26 @@ public class MetricsResourceMethodApplicationListenerIntegrationTest {
// as opposed to a generic error page
config.property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, true);
}
+
+ @Override
+ protected void configurePostResourceHandling(ServletContextHandler context) {
+ context.setErrorHandler(new ErrorHandler() {
+ @Override
+ public void handle(
+ String target,
+ Request baseRequest,
+ HttpServletRequest request,
+ HttpServletResponse response
+ ) throws IOException {
+ handledException = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+ // expect resource handing handledException somewhere in the change
+ super.handle(target, baseRequest, request, response);
+ }
+ });
+ }
}
- @Produces("application/json")
+ @Produces(MediaType.APPLICATION_JSON)
@Path("/private")
private static class PrivateResource {
@GET
