简体   繁体   English

处理scala期货的意外例外

[英]Handling unexpected exceptions on scala Futures

When using some code like the following: 使用如下代码时:

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

Scala throws the following exception: 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)

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. 我正在使用concurrent.ExecutionContext.Implicits.global ,我认为onComplete是在这个全局执行上下文中执行的。 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 ? 我是否必须明确使用try ... catch以便在onComplete发生意外情况时保护我的应用程序?

Thank you 谢谢

IIRC, this was an issue only in the very earliest implementation. IIRC,这只是在最早的实施中才出现的问题。

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. 一切都得到了处理。

First of all, the NullPointerException you get has nothing to do with the future; 首先,你得到的NullPointerException与未来无关; it does not happen inside the Future block. 它不会发生在Future块中。

What you can do, is wrapping code that might return null in Option() . 你可以做的是包装可能在Option()返回null代码。
Your code would then look like this: 您的代码将如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM