Выбрасывание исключения из scala.параллельный.Будущее


Я пытался воспроизвести эту проблему Как мне получить исключения, брошенные в будущем Scala? используя scala.concurrent.Future и я ожидал, что исключение будет проглочено, но этого, похоже, не происходит. Какие-нибудь объяснения?

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") } }
1 5

1 ответ:

Фьючерсов сделать Не глотать исключения (по крайней мере, не в обычном смысле этого слова, что означает "поймать и выбросить"). Когда вы бросаете исключение в будущем (либо в теле map/flatMap или при использовании Future.apply), исключение действительно не распространяется в текущий поток, но сохраняется в будущем и становится результатом будущего. Действительно, конечный результат будущего - это Try[T], поэтому он будет завершен либо правильным результатом типа T (a Success[T]), или С a Throwable (Failure[T]).

Другой ключевой момент заключается в том, что при вызове Await.result вы в основном просите заблокировать текущий поток, ожидая конечного результата в будущем, будь то правильный результат или исключение. В случае исключения он будет переосмыслен в точке, где вызывается Await.result. Если вы не хотите, чтобы исключение было переосмыслено, вы можете использовать Await.ready вместо этого. Он будет ждать завершения будущего и просто вернет само будущее, независимо от того, завершилось ли оно нормально или нет. через исключение. Затем вы можете получить результат будущего через Future.value