在Play for Scala方法中捕获异常

时间:2017-07-06 02:29:27

标签: scala playframework playframework-2.0

这个Play for Scala方法(应该返回Future[play.api.mvc.Result])调用另一个方法run,这个方法可能会引发异常。如果run没有抛出异常,则该方法应返回ret等于0的Json。如果run确实会抛出异常,那么该方法应该使用ret等于1重新调整Json。

问题是OnComplete抛出了编译错误:

  

类型不匹配;发现:所需单位:   scala.concurrent.Future [play.api.mvc.Result]

如何解决这个问题?

   def test (req:Int) : Future[play.api.mvc.Result] = {

       val future = run(req)  
       future.map {
          result => 
               val json = JsObject(Seq(
                          "rs" -> Json.toJson(result),
                          "ret" -> JsString("0")
                      ))
               Ok(json)
           }

       future.onComplete { // <-- compilation error
              case Success(_) => // do nothing
              case Failure(ex) => {
                  val json = JsObject(Seq(
                         "msg" -> JsString(ex.getMessage),
                         "ret" -> JsString("1")
                    ))
                  Ok(json)
              }
            }

   }

1 个答案:

答案 0 :(得分:1)

在Scala中,方法中最后一个表达式的结果成为方法的返回值。 future.onComplete返回一个Unit,它使函数体“返回”一个单位。

您真正想要的是recover

def test (req:Int) : Future[play.api.mvc.Result] = {
    run(req)
        .map(result => Ok(JsObject("rs" -> ..., "ret" -> 0)))
        .recover({ case NonFatal(ex) => 
            Ok(JsObject(Seq("msg" -> ..., "ret" -> 1))
        })
}

另请注意,map会返回新的未来,因此在您的示例中,您将onComplete回调附加到run返回的未来,包括json处理;因此,map onComplete分支机构无法捕获Failure(ex)来电中的失败。正如你所看到的,我在上面的代码片段中已经纠正了这一点。