Handling unexpected exceptions on scala Futures

﹥>﹥吖頭↗ 提交于 2019-12-24 17:44:13

问题


When using some code like the following:

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

Scala throws the following exception:

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)

This would be OK, since I am not handling any exceptions. The problem is that my application hangs completely.

I am using concurrent.ExecutionContext.Implicits.global and I think onComplete is executed in this global execution context. The problem is that it seems like the execution context stops accepting any work and and the application just hangs.

Do I have to explicitly use try ... catch so that I protect my app in case something unexpected happens in onComplete?

Thank you


回答1:


IIRC, this was an issue only in the very earliest implementation.

You can supply a handler or "reporter":

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> 

Everything is handled.




回答2:


First of all, the NullPointerException you get has nothing to do with the future; it does not happen inside the Future block.

What you can do, is wrapping code that might return null in Option().
Your code would then look like this:

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


来源:https://stackoverflow.com/questions/25709602/handling-unexpected-exceptions-on-scala-futures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!