斯卡拉 – 为什么未来的恢复没有捕获例外?
我正在使用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) } } }) 它在99%的时间工作正常,但有时可能会失败(为什么,这不是问题)。 我想在一个错误的情况下恢复,所以我补充说: recover { case _ => BadRequest("")} 但这并不能弥补我的错误。 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的未来文档,我很为难,为什么恢复不适合我。 有人知道为什么吗我想念什么才能整理出来? 解决方法
为什么它失败了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()返回一个未来。未来可能代表着未曾发生的事情。如果这个东西引发异常,你可以在恢复过程中处理这个异常。然而,在你的情况下,错误发生在未来甚至被创建之前,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) } 显然这不行,因为你从来没有创造过未来的第一个地方beacuse异常抛出之前的代码创造未来发生了。 所以解决方案是将您的调用包装到一个try catch块中的UserDao()。getStuffOf(userId = userId).toList()),或者找出为什么它以任何方法调用失败,并在那里捕获异常,并返回失败的未来。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |