gpt4 book ai didi

scala - 为什么Future的恢复未捕获异常?

转载 作者:行者123 更新时间:2023-12-03 11:47:36 27 4
gpt4 key购买 nike

我正在使用Scala,Play Framework 2.1.x和reactmongo驱动程序。

我有一个api调用:

def getStuff(userId: String) = Action(implicit request => {
Async {
UserDao().getStuffOf(userId = userId).toList() map {
stuffLst => Ok(stuffLst)
}
}
})

它在99%的时间内都能正常工作,但有时可能会失败(与为什么无关,这不是问题)。

我想在出现错误的情况下恢复,所以我添加了:
recover { case _ => BadRequest("")}

但这不能使我从错误中恢复过来。
我在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)

这将按预期返回1。
我目前用以下方式包装异步:
try{
Async {...}
} catch {
case _ => BadRequest("")
}

这就捕获了错误。

我在网上浏览了一些Scala的Future文档,但我感到困惑为什么恢复对我不起作用。

有人知道为什么吗?我想念什么呢?

最佳答案

为什么失败实际上很重要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("")}
}
})

因此, UserDao().getStuffOf(userId = userId).toList()返回您的 future 。 future 代表着尚未发生的事情。如果该事件引发异常,则可以在恢复中处理该异常。但是,在您的情况下,错误甚至在创建future之前就已发生, UserDao().getStuffOf(userId = userId).toList()调用引发了异常,而不返回future。因此,恢复 future 的调用将永远不会执行。这等效于在Scala复制代码中执行此操作:
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) }

显然这是行不通的,因为您从来没有首先创建过 future ,因为在创建 future 的代码发生之前就抛出了异常。

因此,解决方案是将对 UserDao().getStuffOf(userId = userId).toList()的调用包装在try catch块中,或者找出您调用的任何方法失败的原因,然后在其中捕获异常,并返回失败的将来。

关于scala - 为什么Future的恢复未捕获异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19431825/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com