这个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)
}
}
}
答案 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)
来电中的失败。正如你所看到的,我在上面的代码片段中已经纠正了这一点。