I was trying to reproduce this issue How do I get hold of exceptions thrown in a Scala Future? using scala.concurrent.Future
and I was expecting the exception to be swallowed but it doesn't seem to happen. Any explanation?
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
def runWithTimeout[T](timeoutMs: Long)(f: => Future[T]) : T = {
Await.result(f, timeoutMs.millis)
}
runWithTimeout(50) { Future { "result" } }
runWithTimeout(50) { Future { throw new Exception("deliberate") } }
Futures do not swallow exceptions (at least not in the usual sense, which means "catch and discard"). When you throw an exception in a future (either in the body of map
/flatMap
or when using Future.apply
), the exception indeed is not propagated into the current thread, but it is preserved in the future and becomes the future's result. Indeed a future's eventual result is a Try[T]
, so it will be completed either with a proper result of type T
(a Success[T]
), or with a Throwable
(Failure[T]
).
Another key point is that when you call Await.result
you are basically asking to block the current thread by waiting on the eventual result of the future, be it a proper result or an exception. In the case of an exception, it will be rethrown at the point where Await.result
is called.
If you don't want the exception to be rethrown, you can use Await.ready
instead. It will wait for the future's completion and just return the future itself, whether it completed normally or through an exception. Then you can retrieve the future's result via Future.value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With