如果Scala未来失败,并且没有“观察”失败的延续(或者唯一的延续使用map / flatMap并且在失败的情况下不运行),那么错误将无法检测到。我希望至少记录这些错误,所以我可以找到错误。
我使用术语“观察到的错误”,因为在.Net Tasks中,当GC收集Task对象时,有机会捕获“未观察到的任务异常”。类似地,使用同步方法,可以记录终止线程的未捕获异常。
在Scala期货中,“观察”失败意味着某些延续或其他代码会在未来处置之前读取存储在未来值中的Exception。我知道最终确定不是确定性的或可靠的,并且可能这就是为什么它不能用于捕获未处理的错误,尽管.Net确实成功地做到了这一点。
有没有办法在Scala中实现这一目标?如果没有,我应该如何组织我的代码以防止未处理的错误错误?
今天我有andThen checkResult
附加到各种未来。但是很难知道何时使用它以及何时不使用:如果库方法返回Future,它不应该checkResult并记录错误本身,因为库用户可能会处理失败,因此责任落在用户身上。当我编辑代码时,我有时需要添加检查,有时需要删除它们,这种手动管理肯定是错误的。
答案 0 :(得分:5)
您可以在返回Future的函数中使用Future.recover
。
例如,在最简单的情况下,您可以“记录”错误并重新抛出原始异常:
def libraryFunction(): Future[Int] = {
val f = ...
f.recover {
case NonFatal(t) =>
println("Error : " + t)
throw t
}
}
请注意使用NonFatal
来匹配捕捉合理的所有异常类型
如果你愿意,那个恢复块可以同样返回一个替代结果。
答案 1 :(得分:5)
我已经得出结论,没有办法一般性地注意到Scala期货中未处理的错误。