Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed enhancement: Provide a way to register exception handlers for specific exceptions #19

Closed
juanavelez opened this issue Mar 2, 2018 · 3 comments

Comments

@juanavelez
Copy link

The exception handling is very good but I think It'd be great if one could register ExceptionHandlers for specific exceptions. A proposal is to add a method to the ExceptionHandler interface that returns the list of exceptions it handles. If the list returned is null/empty, then it would handle any exception, otherwise the ExceptionHandler would handle the specific exception.

public interface ExceptionHandler<T extends Throwable> extends HttpResponseWriter<T> {
    default List<Throwable> getHandledExceptions() {
        return Collections.emptyList();
    }
}

For example, I need to raise a RuntimeException (BadRequestException) that I'd like the BadRequestExceptionHandler to handle. I can also raise another RuntimeException (UnauthorizedException) that I'd like the UnauthorizedExceptionHandler to handler. The BadRequestExceptionHandler would return a 400 HTTP status whereas UnauthorizedExceptionHandler would return a 401 HTTP status.

@drejc
Copy link
Member

drejc commented Mar 3, 2018

Sure ... but this functionality is actually already possible ... for instance ... if you annotate a method with @CatchWith you can list multiple exception handlers:

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("multi/{bang}")
@CatchWith({IllegalArgumentExceptionHandler.class, WebApplicationExceptionHandler.class, MyExceptionHandler.class})
public String returnMultiBang(@PathParam("bang") String bang) throws ExecuteException {

		switch (bang) {
			case "one":
				throw new ExecuteException(405, "HTTP 405 Method Not Allowed");

			case "two":
			default:
				throw new IllegalArgumentException("Bang!");

			case "three":
				throw new NumberFormatException("WHAT!");

			case "four":
				throw new AbstractMethodError("ADIOS!");
		}
	}

where:

  • public class IllegalArgumentExceptionHandler implements ExceptionHandler<IllegalArgumentException> {
  • public class WebApplicationExceptionHandler implements ExceptionHandler<WebApplicationException> {
  • public class MyExceptionHandler implements ExceptionHandler<Throwable> {

Exception handlers are used as listed ... first one matching the exception will be used.

Same logic applies globally when you register a global exception handler:
RestRouter.getExceptionHandlers().register(IllegalArgumentExceptionHandler.class, WebApplicationExceptionHandler.class, MyExceptionHandler.class); OR
RestBuilder...errorHandler(IllegalArgumentExceptionHandler.class, WebApplicationExceptionHandler.class, MyExceptionHandler.class)

So in your case create two exception handlers ... for each specific exception ...

@juanavelez
Copy link
Author

I see, the exception handler chosen is based on the Parameterized Type of the interface. So I need to create ExceptionHandlers whose type argument match the Exceptions I want to capture.

@drejc
Copy link
Member

drejc commented Mar 3, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants