package io.undertow.server.handlers; import io.undertow.Handlers; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import io.undertow.testutils.DefaultServer; import io.undertow.testutils.HttpClientUtils; import io.undertow.testutils.TestHttpClient; import java.io.IOException; import io.undertow.util.StatusCodes; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(DefaultServer.class) public class ExceptionHandlerTestCase { @Test public void testExceptionMappers() throws IOException { HttpHandler pathHandler = Handlers.path() .addExactPath("/", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseSender().send("expected"); } }) .addExactPath("/exceptionParent", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new ParentException(); } }) .addExactPath("/exceptionChild", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new ChildException(); } }) .addExactPath("/exceptionAnotherChild", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new AnotherChildException(); } }) .addExactPath("/illegalArgumentException", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new IllegalArgumentException(); } }); HttpHandler exceptionHandler = Handlers.exceptionHandler(pathHandler) .addExceptionHandler(ChildException.class, new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseSender().send("child exception handled"); } }) .addExceptionHandler(ParentException.class, new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseSender().send("parent exception handled"); } }) .addExceptionHandler(Throwable.class, new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseSender().send("catch all throwables"); } }); DefaultServer.setRootHandler(exceptionHandler); TestHttpClient client = new TestHttpClient(); try { HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/"); HttpResponse result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("expected", HttpClientUtils.readResponse(result)); get = new HttpGet(DefaultServer.getDefaultServerURL() + "/exceptionParent"); result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("parent exception handled", HttpClientUtils.readResponse(result)); get = new HttpGet(DefaultServer.getDefaultServerURL() + "/exceptionChild"); result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("child exception handled", HttpClientUtils.readResponse(result)); get = new HttpGet(DefaultServer.getDefaultServerURL() + "/exceptionAnotherChild"); result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("parent exception handled", HttpClientUtils.readResponse(result)); get = new HttpGet(DefaultServer.getDefaultServerURL() + "/illegalArgumentException"); result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("catch all throwables", HttpClientUtils.readResponse(result)); } finally { client.getConnectionManager().shutdown(); } } @Test public void testReThrowUnmatchedException() throws IOException { HttpHandler pathHandler = Handlers.path() .addExactPath("/", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new IllegalArgumentException(); } }); // intentionally not adding any exception handlers final HttpHandler exceptionHandler = Handlers.exceptionHandler(pathHandler); DefaultServer.setRootHandler(exceptionHandler); TestHttpClient client = new TestHttpClient(); try { HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/"); HttpResponse result = client.execute(get); Assert.assertEquals(StatusCodes.INTERNAL_SERVER_ERROR, result.getStatusLine().getStatusCode()); HttpClientUtils.readResponse(result); } finally { client.getConnectionManager().shutdown(); } } @Test public void testAttachException() throws IOException { HttpHandler pathHandler = Handlers.path() .addExactPath("/", new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { throw new IllegalArgumentException(); } }); final HttpHandler exceptionHandler = Handlers.exceptionHandler(pathHandler) .addExceptionHandler(IllegalArgumentException.class, new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseSender().send("exception handled"); } }); DefaultServer.setRootHandler(new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { Throwable throwable = exchange.getAttachment(ExceptionHandler.THROWABLE); Assert.assertNull(throwable); exceptionHandler.handleRequest(exchange); throwable = exchange.getAttachment(ExceptionHandler.THROWABLE); Assert.assertTrue(throwable instanceof IllegalArgumentException); } }); TestHttpClient client = new TestHttpClient(); try { HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/"); HttpResponse result = client.execute(get); Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); Assert.assertEquals("exception handled", HttpClientUtils.readResponse(result)); } finally { client.getConnectionManager().shutdown(); } } private static class ParentException extends Exception {} private static class ChildException extends ParentException {} private static class AnotherChildException extends ParentException {} }