处理scala期货的意外例外

时间:2014-09-07 11:15:23

标签: scala concurrency future

使用以下代码时:

scala> Future { null } onComplete { case Success(v) => v.toString }

Scala抛出以下异常:

scala> java.lang.NullPointerException
    at $line14.$read$$iw$$iw$$anonfun$2.apply(<console>:11)
    at $line14.$read$$iw$$iw$$anonfun$2.apply(<console>:11)
    at     scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
    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)

这没关系,因为我没有处理任何例外。问题是我的应用程序完全挂起。

我正在使用concurrent.ExecutionContext.Implicits.global,我认为onComplete在此全局执行上下文中执行。问题是,执行上下文似乎停止接受任何工作,并且应用程序只是挂起。

我是否必须明确使用try ... catch,以便在onComplete发生意外情况时保护我的应用?

谢谢

2 个答案:

答案 0 :(得分:3)

IIRC,这只是最早实施的问题。

您可以提供处理程序或&#34;记者&#34;:

scala> import util._
import util._

scala> import concurrent._
import concurrent._

scala> ExecutionContext.fromExecutor(null, (t: Throwable) => println(s"Hi, $t"))
res0: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@221a3fa4

scala> implicit val x = res0
x: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@221a3fa4

scala> Future { null } onComplete { case Success(v) => v.toString }
<console>:16: warning: match may not be exhaustive.
It would fail on the following input: Failure(_)
              Future { null } onComplete { case Success(v) => v.toString }
                                         ^
Hi, java.lang.NullPointerException

scala> 

一切都得到了处理。

答案 1 :(得分:0)

首先,你得到的NullPointerException与未来无关;它不会发生在Future区块内。

您可以做的是包装可能会在Option()中返回null的代码 您的代码将如下所示:

Future { Option(mightBeANull) } onComplete { case Success(v) => v.map(_.toString) }