Skip to content

Instantly share code, notes, and snippets.

@richdougherty
Created February 10, 2014 23:27
Show Gist options
  • Select an option

  • Save richdougherty/8926339 to your computer and use it in GitHub Desktop.

Select an option

Save richdougherty/8926339 to your computer and use it in GitHub Desktop.
Handle ResultExceptions thrown by actions by adding a @ResultExceptionHandling annotation
@Transactional
@ResultExceptionHandling
public static Result list(int page, String sortBy, String order, String filter) {
if (page == 2) throw new ResultException(ok("transaction rolled back"));
return ok(
list.render(
Computer.page(page, 10, sortBy, order, filter),
sortBy, order, filter
)
);
}
package actions;
import play.mvc.*;
import play.mvc.Http.*;
public class ResultException extends RuntimeException {
private SimpleResult result;
public ResultException(SimpleResult result) {
this.result = result;
}
public SimpleResult getResult() {
return result;
}
}
package actions;
import play.mvc.*;
import play.mvc.Http.*;
import java.util.*;
import java.lang.annotation.*;
@With(ResultExceptionHandlingAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ResultExceptionHandling {
String value() default "default";
boolean readOnly() default false;
}
package actions;
import play.libs.F;
import play.mvc.*;
import play.mvc.Http.*;
public class ResultExceptionHandlingAction extends Action<ResultExceptionHandling> {
public F.Promise<SimpleResult> call(final Context ctx) throws Throwable {
try {
F.Promise<SimpleResult> delegateResult = delegate.call(ctx);
F.Promise<SimpleResult> handledResult = delegateResult.recover(new F.Function<Throwable,SimpleResult>() {
public SimpleResult apply(Throwable throwable) throws Throwable {
if (throwable instanceof ResultException) {
// Delegate threw a ResultException, convert it to a SimpleResult
ResultException resultException = (ResultException) throwable;
return resultException.getResult();
} else {
// Rethrow all other exceptions, Play will present the default error page
throw throwable;
}
}
});
return handledResult;
} catch (ResultException resultException) {
// Shouldn't need to catch exceptions here; they should always be handled
// by F.Promise.recover(). Unfortunately there is a bug in Play that means
// exceptions thrown by the first delegate aren't wrapped in an F.Promise.
// So for the meantime we need to handle them here too.
return F.Promise.pure(resultException.getResult());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment