在 Play for Scala 方法中捕获异常

Catching exception in Play for Scala method

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

问题是 OnComplete 抛出一个编译错误:

type mismatch; found : Unit required: 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)
              }
            }

   }

在 Scala 中,方法中最后一个表达式的结果成为方法的 return 值。 future.onComplete returns 一个 Unit,它使函数体 "return" 成为一个 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 return 的新未来,因此在您的示例中,您将 onComplete 回调附加到 return 由 [=15] 编辑的未来=],其中 包括 json 处理;因此 map 调用 中的失败将不会被 onComplete Failure(ex) 分支捕获 。如您所见,我已在上面的代码片段中更正了这一点。