2013-09-29 25 views
5

我正在編寫一個控制器方法,該方法在調用返回Future的函數時也可能會拋出異常。我無法弄清楚如何捕捉和處理這個異常。如何處理將來發生在scala中的異常

這裏是我的嘗試:

def openIDCallback = Action { implicit request => 
    Async (
     Try(OpenID.verifiedId) match { 
     case Failure(thrown) => { 
      PurePromise(Ok("failed: " + thrown)) 
     } 
     case Success(successResult) => { 
      successResult.map(userInfo => { 
      Ok(userInfo.id + "\n" + userInfo.attributes) 
      }) 
     } 
     } 
    ) 
    } 

OpenID.verifiedId是從播放的OpenID API函數返回的未來[的UserInfo。下面是該函數的源:

def verifiedId(queryString: Map[String, Seq[String]]): Future[UserInfo] = { 
    (queryString.get("openid.mode").flatMap(_.headOption), 
     queryString.get("openid.claimed_id").flatMap(_.headOption)) match { // The Claimed Identifier. "openid.claimed_id" and "openid.identity" SHALL be either both present or both absent. 
     case (Some("id_res"), Some(id)) => { 
     // MUST perform discovery on the claimedId to resolve the op_endpoint. 
     val server: Future[OpenIDServer] = discovery.discoverServer(id) 
     server.flatMap(directVerification(queryString))(internalContext) 
     } 
     case (Some("cancel"), _) => PurePromise(throw Errors.AUTH_CANCEL) 
     case _ => PurePromise(throw Errors.BAD_RESPONSE) 
    } 
    } 

如上所示,函數可以返回PurePromise(扔Errors.AUTH_CANCEL)和PurePromise(扔Errors.BAD_RESPONSE)。我在嘗試解決正確處理成功,但在例外情況,我得到:

play.api.Application$$anon$1: Execution exception[[AUTH_CANCEL$: null]] 

我的問題是我怎麼捕獲並處理這些異常在我的控制方法?

回答

10

您應該使用的Future代替Tryrecover方法是這樣的:

Async (
    OpenID.verifiedId. 
    map{userInfo => Ok(userInfo.id + "\n" + userInfo.attributes)}. 
    recover{ case thrown => Ok("failed: " + thrown) } 
) 

Try可以幫助你在情況verifiedId拋出一個異常,而不是返回Future的。在你的情況下,verifiedId成功返回Future(即使在此Future中會出現異常)。

+0

謝謝 - 我確實看着恢復,但不瞭解PartialFunction的概念。你的例子爲我工作並闡明瞭這個概念。 –

+0

@KresimirNesek:'PartialFunction'(和模式匹配)是scala中最重要和最有用的工具之一。見'9。 [Scala標籤信息](http://stackoverflow.com/tags/scala/info)中的模式匹配部分。 – senia

相關問題