A short article to talk about an interesting issue concerning Scala 2.10.0 Future that might interest you.
Fatal exception is thrown in your
Future callback, it’s not caught by the
Future and is thrown to the provided
But the current default Scala global
ExecutionContext doesn’t register an
UncaughtExceptionHandler for these fatal exceptions and your
Future just hangs forever without notifying anything to anybody.
This issue is well known and a solution to the problem has already been merged into branch 2.10.x. But this issue is present in Scala 2.10.0 so it’s interesting to keep this issue in mind IMHO. Let’s explain clearly about it.
Exceptions can be contained by Future
Let’s write some stupid code with Futures.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
You can see that a
Futurecan contain an
Exception(or more generally
Fatal Exceptions can’t be contained by Future
If you look in Scala 2.10.0 Future.scala, in the scaladoc, you can find:
1 2 3 4
and in the code, in several places, in
flatMap for example, you can read:
1 2 3 4 5
This means that every
Throwablethat is Fatal can’t be contained in the
What’s a Fatal Throwable?
To define what’s fatal, let’s see what’s declared as non-fatal in NonFatal ScalaDoc.
1 2 3 4 5 6 7
Let’s consider Fatal exceptions are just critical errors that can’t be recovered in general.
So what’s the problem?
It seems right not to catch fatal errors in the `Future, isn’t it?
But, look at following code:
1 2 3 4 5 6
Future doesn’t contain the Fatal Exception as expected.
But where is my Fatal Exception if it’s not caught??? No crash, notification or whatever?
There should be an `UncaughtExceptionHandler at least notifying it!
The problem is in the default Scala
As explained in this issue, the exception is lost due to the implementation of the default global
ExecutionContext provided in Scala.
This is a simple ForkJoin pool of threads but it has no
UncaughtExceptionHandler. Have a look at code in Scala 2.10.0 ExecutionContextImpl.scala
1 2 3 4 5 6 7 8 9 10
Here it’s quite clear: there is no registered `UncaughtExceptionHandler.
What’s the consequence?
Your Future hangs forever
1 2 3 4
As you can see, you can wait as long as you want, the Future is never redeemed properly, it just hangs forever and you don’t even know that a Fatal Exception has been thrown.
As explained in the issue, please note, if you use a custom
ExecutionContext based on
SingleThreadExecutor, this issue doesn’t appear!
1 2 3 4 5 6 7 8 9 10 11
In Scala 2.10.0, if you have a Fatal Exception in a Future callback, your Future just trashes the Fatal Exception and hangs forever without notifying anything.
Hopefully, due to this already merged PR, in a future delivery of Scala 2.10.x, this problem should be corrected.
To finish, in the same old good issue, Viktor Klang also raised the question of what should be considered as fatal or not:
there’s a bigger topic at hand here, the one whether NotImplementedError, InterruptedException and ControlThrowable are to be considered fatal or not.
Meanwhile, be aware and take care ;)