John Doe
John Doe

Reputation: 277

How to encapsulate Play's Status in Scala?

Multiple times throughout my code I use the following pattern to recover a failing future:

myFuture.recover {
        case t =>
          Logger.error(s"foo bar foo, exception: ${t.getMessage}.")
       InternalServerError(views.html.error(request, Messages("error.foo")))
      }

I am now looking for a way to encapsulate this behavior in order to remove code duplication. I tried to wrap it in a class but strangely, I cannot resolve InternalServerError inside the apply method.

class MyError(t: Throwable, logMsg: String, message: String) {
  def apply(t: Throwable, logMsg: String, message: String) = {
    Logger.error(logMsg)
  InternalServerError(views.html.error(request, message))
  }
}

Any idea how I can solve this? Also how do I go about the request parameter?

Upvotes: 0

Views: 58

Answers (2)

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Code Reuse

Use implicit class to extend the functionality of the Future and put the implicit class inside the package object or object. Import the package object/object and use the code whenever you need it.

object common {
 implicit class FutureUtils(future: Future[Result]) {
  def graceful(implicit req: Request, msg: String): Future[Result] = {
    future.recover { case th =>
      import play.api.mvc.Results._
      Logger.error(logMsg)
      InternalServerError(views.html.error(request, message))
    }
  }
 }
}


import common._

class Foo extends Controller {
  def bar = Action { implicit req => 
    myFuture.graceful(Messages("foo.bar"))
  }
}

Upvotes: 3

Ori Popowski
Ori Popowski

Reputation: 10662

I'm quite sure you meant the apply method to be part of the companion object, not the class itself.

As for the resolution problem, you'll have to import it like this:

object MyError {
  def apply(t: Throwable, logMsg: String, message: String, request: Request): Result = {
    import play.api.mvc.Results._
    Logger.error(logMsg)
    InternalServerError(views.html.error(request, message))
  }
}

Then you can do

MyError(t, "log something", "message", request)

as the last line inside a controller Action

Upvotes: 1

Related Questions