Play 2.6.x throwing exceptions

I am using playframework 2.6.x for my Java application.
When I detected that the user request is invalid I would like to return 4XX with meaningful message.
In my Controller I could just
return badRequest("message");
But how do I do this somewhere deeper in the stack?
If I were using Scala the I could use Try or Either returns all the way to controller (even that is annoying depending on how deep in the stack we are talking about)

I was hoping that I can just
throw new BadRequest("message");
that DefaultHttpExceptionHandler converts to HTTP 400 result; with appropriate message from the exception.
But I did not find such a thing.

I can be rolling my own exception handler and exception types. But was trying to avoid that if there is existing exception type that I can use.

What you are looking for is HttpErrorHandler. Link to docs.

I am not sure that answers my question.

May be example would help:

class MyController {

Result myPutResourceHandler(req) {
     // get A from request here
     try {
     someOtherObj.storeA(objA);
     return ok("success");
     } catch (IllegalArgumentException e) {
           return badRequest(e.getMessage());
     } catch (Throwable t) {
           return serverError(t.getMessage);
     }
}
}

class SomeOtherObj {
    void storeA(A objA) {
        if (!isValid(objA)) {
             // need to cause bad request
             throw new IllegalArgumentException("helpful message");
        }
    }
}

I am looking to throw new BadRequest() and not do any handling in my controller and not write any handler. This is not about how to handle client error but how to easily throw client error in my code.
I found
play.mvc.results (Play! API)
It looks promising since Result is an exception.

But I do not find play.mvc.results package in my jars and could not find any examples of how to use that.

Any help appriciated.

So you can implement your own HttpErrorHandler like this

import com.google.common.base.Throwables;
import com.typesafe.config.Config;
import play.Environment;
import play.api.OptionalSourceMapper;
import play.api.routing.Router;
import play.http.DefaultHttpErrorHandler;
import play.mvc.Http;
import play.mvc.Result;
import play.mvc.Results;

import javax.inject.Inject;
import javax.inject.Provider;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

public class ErrorHandlerExample extends DefaultHttpErrorHandler {

	@Inject
	public ErrorHandlerExample(Config config, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) {
		super(config, environment, sourceMapper, routes);
	}

	@Override
	public CompletionStage<Result> onServerError(Http.RequestHeader request, Throwable exception) {
		for (Throwable cause : Throwables.getCausalChain(exception)) {
			if (cause instanceof BadRequestException) {
				return CompletableFuture.completedFuture(Results.badRequest(cause.getMessage()));
			}
		}
		return super.onServerError(request, exception);
	}

	public static class BadRequestException extends RuntimeException {

		public BadRequestException(String message) {
			super(message);
		}

	}

}

And then you can just throw BadRequestException anywhere and the server will respond with 400.

Thanks!
That’s what I meant in my first post when I said:

I can be rolling my own exception handler and exception types. But was trying to avoid that if there is existing exception type that I can use.

Its just that play.mvc.results
looked pretty close to the exception types I ll have to write so I was hoping this functionality is already available.

But given that you have kindly written all the code for me, I will copy it and call it Built-In and move on :slight_smile:

I just realized that the link you used is actually for Play 1.x, so it’s irrelevant.

1 Like

So they had this pattern of returning Result by throwing exception back then?

I don’t know much about Play 1.x but that’s what it looks like to me. The same kind of functionality can be easily achieved with my sample code though.

1 Like