sam*_*amz 20 scala playframework reactivemongo
我正在使用Scala,Play Framework 2.1.x和reactivemongo驱动程序.
我有一个api电话:
def getStuff(userId: String) = Action(implicit request => {
Async {
UserDao().getStuffOf(userId = userId).toList() map {
stuffLst => Ok(stuffLst)
}
}
})
Run Code Online (Sandbox Code Playgroud)
它在99%的时间内工作正常,但有时可能会失败(无关紧要的原因,这不是问题).
我想在出现错误的情况下恢复,所以我补充说:
recover { case _ => BadRequest("")}
Run Code Online (Sandbox Code Playgroud)
但这并没有让我从错误中恢复过来.
我在scala控制台上尝试了相同的概念并且它有效:
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
var f = future { throw new Exception("") } map {_ => 2} recover { case _ => 1}
Await.result(f, 1 nanos)
Run Code Online (Sandbox Code Playgroud)
这将按预期返回1.
我目前用以下方法包装Async:
try{
Async {...}
} catch {
case _ => BadRequest("")
}
Run Code Online (Sandbox Code Playgroud)
这就抓住了错误.
我在网上浏览了一些Scala的未来文档,我很困惑为什么恢复不适合我.
有谁知道为什么?我想错过什么来解决它?
Jam*_*per 42
为什么它失败实际上100%重要.如果我们将代码分布在多行代码中,您就会明白为什么:
def getStuff(userId: String) = Action(implicit request => {
Async {
val future = UserDao().getStuffOf(userId = userId).toList()
val mappedFuture = future.map {
stuffLst => Ok(stuffLst)
}
mappedFuture.recover { case _ => BadRequest("")}
}
})
Run Code Online (Sandbox Code Playgroud)
所以,UserDao().getStuffOf(userId = userId).toList()给你一个未来.未来代表着可能尚未发生的事情.如果该事件抛出异常,您可以在恢复中处理该异常.但是,在您的情况下,错误发生在甚至创建未来之前,UserDao().getStuffOf(userId = userId).toList()调用抛出异常,而不是返回未来.因此,恢复未来的呼吁永远不会被执行.它相当于在Scala repl中执行此操作:
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
var f = { throw new Exception(""); future { "foo" } map {_ => 2} recover { case _ => 1} }
Await.result(f, 1 nanos) }
Run Code Online (Sandbox Code Playgroud)
显然这不起作用,因为你从来没有创造过未来,因为在创建未来的代码发生之前抛出了异常.
因此,解决方法是换您的来电UserDao().getStuffOf(userId = userId).toList()在try catch块,或者找出为什么它的失败在任何你所呼叫,并捕获异常出现,并返回一个失败的未来.
| 归档时间: |
|
| 查看次数: |
16048 次 |
| 最近记录: |