He estado trabajando mi respuesta al Is there a standard Scala function for running a block with a timeout?, y me he encontrado con un problema si se lanza una excepción en un futuro.¿Cómo puedo obtener las excepciones lanzadas en un Scala Future?
def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = {
awaitAll(timeoutMs, future(f)).head.asInstanceOf[Option[T]]
}
Para que
runWithTimeout(50) { "result" } should equal (Some("result"))
runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None)
Pero si tiro una excepción en mi bloque que no se escape, pero se traga - por lo que la siguiente falla con "..no excepción fue arrojado"
intercept[Exception] {
runWithTimeout(50) { throw new Exception("deliberate") }
}.getMessage should equal("deliberate")
SYSERR tiene un seguimiento de la pila con el mensaje
<function0>: caught java.lang.Exception: deliberate
pero no puedo encontrar el lugar en el tiempo de ejecución de Scala que se imprime.
Además de envolver f en otro bloque que detecta excepciones y las propaga si se lanzan, ¿hay alguna forma de persuadir a awaitAll y/o Future para lanzar?
es probable que sea impreso porque se hacía pasar al de la rosca [UncaughtExceptionHandler] (http://download.oracle.com/javase/6/docs/api/java/lang/Thread.UncaughtExceptionHandler.html). Podrías configurar tu propio controlador, pero eso aún no te permitiría lanzar la excepción en un hilo diferente. –
Eche un vistazo a los futuros de Fingales (https://github.com/twitter/finagle), busque "Tiempo de espera" y Akka http://akka.io/docs/akka/1.1.2/scala/futures.html – oluies