diff --git a/http-server-jetty/src/test/groovy/io/micronaut/servlet/jetty/JettyExceptionHandlerSpec.groovy b/http-server-jetty/src/test/groovy/io/micronaut/servlet/jetty/JettyExceptionHandlerSpec.groovy new file mode 100644 index 000000000..c2393e005 --- /dev/null +++ b/http-server-jetty/src/test/groovy/io/micronaut/servlet/jetty/JettyExceptionHandlerSpec.groovy @@ -0,0 +1,81 @@ +package io.micronaut.servlet.jetty + +import groovy.transform.InheritConstructors +import io.micronaut.context.annotation.Property +import io.micronaut.context.annotation.Requires +import io.micronaut.http.HttpRequest +import io.micronaut.http.HttpResponse +import io.micronaut.http.HttpStatus +import io.micronaut.http.MutableHttpResponse +import io.micronaut.http.annotation.Controller +import io.micronaut.http.annotation.Get +import io.micronaut.http.client.HttpClient +import io.micronaut.http.client.annotation.Client +import io.micronaut.http.client.exceptions.HttpClientResponseException +import io.micronaut.http.server.exceptions.ExceptionHandler +import io.micronaut.test.extensions.spock.annotation.MicronautTest +import spock.lang.Specification + +import javax.inject.Inject +import javax.inject.Singleton + +@MicronautTest +@Property(name = "spec.name", value = "JettyExceptionHandlerSpec") +class JettyExceptionHandlerSpec extends Specification { + + @Inject + @Client("/") + HttpClient client + + void "test an exception handler for mutable request works"() { + when: + def resp = client.toBlocking().exchange("/exception") + + then: + resp.status() == HttpStatus.OK + } + + void "test an exception handler returning the body"() { + when: + client.toBlocking().retrieve("/exception/my") + + then: + def ex = thrown(HttpClientResponseException) + ex.response.status() == HttpStatus.INTERNAL_SERVER_ERROR + ex.response.getBody().get() == "hello" + } + + @Controller("/exception") + static class ExceptionController { + + @Get + void throwsEx() { + throw new RuntimeException("bad") + } + + @Get("/my") + void throwsMy() { + throw new MyException("bad") + } + } + + @Singleton + static class MyExceptionHandler implements ExceptionHandler { + @Override + String handle(HttpRequest request, MyException exception) { + "hello" + } + } + + @Singleton + @Requires(property = "spec.name", value = "JettyExceptionHandlerSpec") + static class RuntimeExceptionHandler implements ExceptionHandler> { + @Override + MutableHttpResponse handle(HttpRequest request, RuntimeException exception) { + return HttpResponse.ok() + } + } + + @InheritConstructors + static class MyException extends Exception {} +} diff --git a/servlet-core/src/main/java/io/micronaut/servlet/http/ServletHttpHandler.java b/servlet-core/src/main/java/io/micronaut/servlet/http/ServletHttpHandler.java index 274d11100..5c71a9b33 100644 --- a/servlet-core/src/main/java/io/micronaut/servlet/http/ServletHttpHandler.java +++ b/servlet-core/src/main/java/io/micronaut/servlet/http/ServletHttpHandler.java @@ -825,7 +825,7 @@ private JsonError newJsonError(HttpRequest req, String message) { @SuppressWarnings("unchecked") private ExceptionHandler lookupExceptionHandler(Throwable e) { final Class type = e.getClass(); - return applicationContext.findBean(ExceptionHandler.class, Qualifiers.byTypeArgumentsClosest(type, HttpResponse.class)) + return applicationContext.findBean(ExceptionHandler.class, Qualifiers.byTypeArgumentsClosest(type, Object.class)) .orElse(null); }