2016-09-17 69 views
0

在我的代码多次我用下面的方式来恢复一个失败的未来:如何在Scala中封装Play的状态?

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

我现在正在寻找一种方法,以消除重复代码封装此行为。我试图将它包装在课堂上,但奇怪的是,我无法解决apply方法中的InternalServerError

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参数?

回答

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

谢谢!我非常喜欢这个解决方案。但是,该代码不能在我的盒子上编译。我得到以下错误:'预期的标识符,但'隐式'找到.'。 –

+0

@JohnDoe你必须创建一个'包对象' – pamu

+0

这是一个不错的解决方案,但建议您慎重使用隐含因为它会使代码复杂化很大。 –

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