Jonathan
Jonathan

Reputation: 20375

How to handle exceptions for multiple Route

I'm getting to grips with the Spark Framework and I'm trying to understand the best way of handling exceptions in a uniform way for multiple Routes.

At the moment I have a number of Routes which all handle exceptions along the lines of:

...
catch (final Exception e) {
    ...
    response.status(418);
    return e.getMessage();
}
...

This leaves a lot to be desired, mainly the exception logic is duplicated between them. I know that it can be improved by refactoring but I was wondering if there's something similar to the ExceptionHandler mechanism in Spring where you can perform an action when a particular exception is thrown, e.g.:

@ExceptionHandler(Exception.class)
public void handleException(final Exception e, final HttpServletRequest request) {
    ...executed for the matching exception...
}

So, is there a Spark-esque mechanism for exception handling? I've checked the documentation and come up short. If there isn't, I'll go ahead with my refactoring plans. Thanks.

Upvotes: 9

Views: 7086

Answers (2)

Pixel Elephant
Pixel Elephant

Reputation: 21383

You can handle exceptions like so:

get("/throwexception", (request, response) -> {
    throw new NotFoundException();
});

exception(NotFoundException.class, (e, request, response) -> {
    response.status(404);
    response.body("Resource not found");
});

Example taken from the Spark docs.

Upvotes: 15

Dan
Dan

Reputation: 9

I've been dealing with this very issue. This is what I came up with. It will need tweaking to your environment.

public class ExceptionHandler extends MustacheTemplateHandler
{
private final WrappedHandler inter;

public abstract static class WrappedHandler
{
    public abstract Object handle(Request req, Response res);       
}

public static ExceptionHandler wrap(String path, WrappedHandler internal)
{
    return new ExceptionHandler(path, internal);
}

private ExceptionHandler(String path, WrappedHandler internal) 
{
    super(path);
    inter = internal;
}

@Override
public Object handle(Request req, Response res) 
{
    try 
    {
        return inter.handle(req, res);
    }
    catch (Exception e)
    {
        e.printStackTrace();
        return new ModelAndView(e, "errors");
    }
}
}

and then (using import static):

    get(wrap("/download", new DownloadHandler()));
    post(wrap("/upload", new UploadHandler()));

Upvotes: 0

Related Questions