Await.result(...)Scala 2.10中致命错误和异常处理之间的区别

时间:2014-06-05 23:58:35

标签: scala error-handling

为什么Await.result(f, t)将重新抛出由f引发的异常,而它不会重新抛出致命错误?

是错误还是预期行为?

以下REPL序列再现了行为:

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

scala> import scala.concurrent._
import scala.concurrent._

scala> val ec = scala.concurrent.ExecutionContext.global
ec: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@2d2217da

scala> Await.result(Future{throw new RuntimeException()}(ec), Duration.Inf)
java.lang.RuntimeException
    at $anonfun$1.apply(<console>:15)
    at $anonfun$1.apply(<console>:15)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)


scala> Await.result(Future{throw new LinkageError()}(ec), Duration.Inf)
scala.NotImplementedError: an implementation is missing
    at $line28.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:15)
    at $line28.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:15)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
    (hanging - needs ctrl-c)

两次执行之间的区别在于第一次执行将终止执行,第二次将打印堆栈跟踪然后挂起,永远等待(虽然不确定)。

Edit1:将NotImplementedError替换为LinkageError,因为在{2.1}中修改了NotImplementedError行为,而LinkageError保持不变。

Edit2:添加&#34;致命&#34;描述问题中的错误。

1 个答案:

答案 0 :(得分:1)

这是因为scala.util.NonFatal(在Future的实现中使用)与NotImplementedError不匹配,导致它被视为致命的。在2.11中,这已经改变了,NotImplementedError不再是致命的。请参阅this commit