如何在Scala中封装Play的状态?

时间:2016-09-17 16:56:31

标签: scala playframework playframework-2.2

在我的代码中多次使用以下模式来恢复失败的未来:

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

我现在正在寻找一种封装此行为的方法,以便删除代码重复。我试图将它包装在一个类中,但奇怪的是,我无法在InternalServerError方法中解析apply

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

知道如何解决这个问题吗?另外,我如何查看request参数?

2 个答案:

答案 0 :(得分:3)

代码重用

使用implicit class扩展Future的功能,并将implicit class放在package object或对象中。导入包对象/对象,并在需要时使用代码。

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

答案 1 :(得分:1)

我很确定你的意思是apply方法成为伴侣对象的一部分,而不是类本身。

至于解决问题,你必须像这样导入它:

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

然后你可以做

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

作为控制器Action

内的最后一行