2016-09-17 51 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