John Doe John Doe - 2 months ago 14
Scala Question

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?

Answer

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"))
  }
}