Comment puis-je obtenir les exceptions levées dans un Scala Avenir?

J'ai travaillé ma réponse à Est-il un standard de Scala fonction pour l'exécution d'un bloc avec un délai d'attente?, et l'ont exécuté un problème si une exception est levée dans un Avenir.

  def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = {
    awaitAll(timeoutMs, future(f)).head.asInstanceOf[Option[T]]
  }

De sorte que

runWithTimeout(50) { "result" } should equal (Some("result"))
runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None)

Mais si je jette une exception dans mon quartier, il n'y a pas de fuite, mais il est avalé, de sorte que le suivant échoue avec "..pas une exception a été levée"

intercept[Exception] {
    runWithTimeout(50) { throw new Exception("deliberate") }
}.getMessage should equal("deliberate")

Syserr a une trace de la pile avec le message

<function0>: caught java.lang.Exception: deliberate

mais je ne trouve pas où dans le Scala runtime qui est imprimé.

En dehors de habillage de f dans un autre bloc, qui attrape les exceptions et les propage si jetés, est-il possible de convaincre awaitAll et/ou à venir jeter?

Il est imprimé vraisemblablement parce qu'il s'est passé au fil du UncaughtExceptionHandler. Vous pouvez définir votre propre gestionnaire, mais ce ne serait pas vous permettre de lancer l'exception dans un thread différent.
Jetez un oeil à Fingales terme (github.com/twitter/finagle), recherche pour "Timeout" et Akka akka.io/docs/akka/1.1.2/scala/futures.html

OriginalL'auteur Duncan McGregor | 2011-06-03