Play Framework - throw an exception to return an HTTP response

Hmm, when I write out the title, the idea seems pretty gross. But it makes some boilerplate-type things really nice.

Take, for example, a user profile page. The endpoint looks like fancyapp.com/users/{userId}/. If the user doesn’t exist, you’ll want to throw a 404. And chances are, you’ll be doing the same thing for other models.

Here is something that you might need something like:

public Result viewProfile(long userId) {  
    User user = User.repository.byId(userId);
    if (user == null) {
        return notFound("User does not exist!");
    }

    return ok("user profile!");
}

Wouldn’t it be great if you had, like, a getUserOr404 method? Then you could just do…

public Result viewProfile(long userId) throws ImmediateHttpResponse {  
    User user = getUserOr404(userId);
    return ok("user profile!");
}

What if I told you that such a method exists? All you have to do is believe in yourself.

I mean, it only saves 3 lines here, but think of the possibilities. You could probably even gussy that up a little more…pass in the class that you’re looking for…make it more generic…

Here’s your ErrorHandler class (docs):

public class ErrorHandler extends DefaultHttpErrorHandler {  
    @Override
    public CompletionStage<Result> onServerError(RequestHeader request, Throwable exception) {
        if (exception instanceof ImmediateHttpResponse) {
            return CompletableFuture.supplyAsync(() -> {return (ImmediateHttpResponse) exception;})
                    .thenApply(immediateHttpResponse -> immediateHttpResponse.getResponse());
        }

        return super.onServerError(request, exception);
    }
}

I know that some of that code isn’t too great (my IDE told me so). I’ll fix it up later when I’m feelin’ all learny n stuff.

And then your ImmediateHttpResponse:

public class ImmediateHttpResponse extends Exception {

    private Result response;

    public ImmediateHttpResponse(Result response) {
        this.response = response;
    }

    public Result getResponse() {
        return this.response;
    }
}

I actually stole this from CodeIgniter. There aren't many things that I like about that framework, but I did like this. And then the example was something that Django does, but I forget how it's implemented. I don't think it's with an exception.

And there you have it.