le-doude
le-doude

Reputation: 3367

check that a result is an ok playframework

I am trying to make a slightly better @Cached annotation by making it aware of the parameters of the function I call in my controllers.

so I have this Action :

public class ContextualCachedAction extends Action<ContextualCached> {

    @Override
    public Result call(Context ctx) throws Throwable {
        try {
            String key = makeKey(ctx);
            Integer duration = configuration.duration();
            Result result = (Result) Cache.get(key);
            if (result == null) {
                result = delegate.call(ctx);

                //TODO find a way to cache only successful calls

                Cache.set(key, result, duration);
            }
            return result;
        } catch (RuntimeException e) {
            throw e;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }
    }

    private String makeKey(Context ctx) {
        //makes the key from some parameters in the ctx.request()
    }
}

My question is this : I would like to cache the result of delegate.call() only if it is an Ok(). How can I check for that? Is there a property? a util? or do I need to Ok().getClass().isInstance(result)?

Thanks for any answers and hints.

PS : Why do I want to do that? Because I have some calls that generate few types of different results. Few enough results that caching them could be an option since I don't want to

Upvotes: 6

Views: 4528

Answers (4)

le-doude
le-doude

Reputation: 3367

Just to update this page with the latest 2.3+ Playframework way of doing it.

Result result = //.....
int httpStatus = result.toScala().header().status();

easy enough.

Upvotes: 3

user2029783
user2029783

Reputation: 601

Less sucky approach:

import org.junit.*;
import static org.fest.assertions.Assertions.assertThat;
import static play.test.Helpers.*;

/* do stuff */

Result result = doSomethingWithController();
assertThat(status(result)).isEqualTo(OK);

Works as of 2.2.2.

Upvotes: 8

Zolt&#225;n
Zolt&#225;n

Reputation: 22166

If you know your Result is an instance of play.mvc.Results.Status (which it is if you created it using any of the static helper methods from the play.mvc.Results class) you can cast it to Status, and get a SimpleResult object directly using getWrappedSimpleResult():

Status result = (Status) YourController.actionHandler();
int expected = Results.ok()
        .getWrappedSimpleResult().header().status();
int actual = result.getWrappedSimpleResult().header().status();
Assert.assertEquals(expected, actual);

Upvotes: 2

Marius Soutier
Marius Soutier

Reputation: 11274

An ok result is actually a play.mvc.Results.Status which wraps its Scala counterpart play.api.mvc.Results.Status, which in turn has its status code set to 200.

So you call result.getWrappedResult() and check if the type is right, cast it to PlainResult (the lowest common denominator) and call status.

This looks very ugly though:

  play.api.mvc.Result wrappedResult = result.getWrappedResult();
  if (wrappedResult instanceof play.api.mvc.PlainResult) {
    play.api.mvc.PlainResult plainResult = (play.api.mvc.PlainResult)wrappedResult;
    int code = plainResult.header().status();
    if (code == OK)
      // Cache
  }

Upvotes: 5

Related Questions