2013-09-29 16 views
5

Tôi đang viết một phương thức điều khiển trong khung chơi gọi một hàm trả về một Tương lai cũng có thể ném một Ngoại lệ. Tôi đang gặp khó khăn trong việc tìm ra cách bắt và xử lý Ngoại lệ đó.Làm thế nào để xử lý một ngoại lệ xảy ra trong tương lai trong scala

Đây là những gì tôi đã cố gắng:

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 là chức năng từ OpenID api Play trả về tương lai [UserInfo]. Đây là nguồn gốc của hàm:

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

Như đã trình bày ở trên, chức năng có thể trở lại PurePromise (ném Errors.AUTH_CANCEL) và PurePromise (ném Errors.BAD_RESPONSE). Nỗ lực của tôi tại giải pháp xử lý thành công một cách chính xác, nhưng trên ngoại lệ tôi nhận được:

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

Câu hỏi của tôi là làm cách nào để nắm bắt và xử lý các ngoại lệ này trong phương pháp điều khiển của tôi?

Trả lời

10

Bạn nên sử dụng phương pháp recoverFuture thay vì Try như thế này:

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

Try có thể giúp bạn trong trường hợp verifiedId ném một ngoại lệ thay vì trả lại Future. Trong trường hợp của bạn, số verifiedId trả về thành công Future (ngay cả khi có ngoại lệ trong số Future) này.

+0

Cảm ơn - Tôi đã xem xét khôi phục nhưng không hiểu khái niệm về PartialFunction. Ví dụ của bạn đã làm việc và làm rõ khái niệm cho tôi. –

+0

@KresimirNesek: 'PartialFunction' (và mẫu phù hợp) là một trong những công cụ quan trọng và hữu ích nhất trong scala. Xem '9. Phần khớp mẫu' trong [Thông tin thẻ Scala] (http://stackoverflow.com/tags/scala/info). – senia

Các vấn đề liên quan