如何获得Scala Future中抛出的异常? [英] How do I get hold of exceptions thrown in a Scala Future?

查看:587
本文介绍了如何获得Scala Future中抛出的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在处理有一个标准的Scala功能来运行一个超时的块吗? ,并且在未来抛出异常时遇到问题。

I've been working up my answer to Is there a standard Scala function for running a block with a timeout?, and have run into a problem if an exception is thrown in a Future.

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

所以

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

但是,如果我在我的块中抛出异常, t泄漏,但被吞噬 - 以下失败与..no异常被抛出

But if I throw an exception in my block it doesn't leak, but is swallowed - so that the following fails with "..no exception was thrown"

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

Syserr有一个堆栈跟踪消息

Syserr has a stack trace with the message

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

但我找不到打印的Scala运行时的位置。

but I can't find where in the Scala runtime that is printed.

除了在另一个块中包装f,捕获异常并传播它们,如果抛出,有没有办法说服awaitAll和/或将来抛出?

Apart from wrapping f in another block which catches exceptions and propagates them if thrown, is there any way to persuade awaitAll and/or Future to throw?

推荐答案

简答案:否。

例外情况不要你想做什么在线程上下文中工作,因为你想知道t他在调用者中例外,并且在未来的线程中发生异常。

Exceptions don't do what you want when you're working in a threaded context, because you want to know about the exception in the caller, and the exception happens in the future's thread.

相反,如果你想知道什么是异常,你应该返回一个 [Exception,What YouWant] - 当然,你必须在将来捕获这个例外,并将其打包。

Instead, if you want to know what the exception was, you should return an Either[Exception,WhatYouWant]--of course, you have to catch that exception within the future and package it up.

scala> scala.actors.Futures.future{
  try { Right("fail".toInt) } catch { case e: Exception => Left(e) }
}
res0: scala.actors.Future[Product with Serializable with Either[Exception,Int]] = <function0>

scala> res0()   // Apply the future
res1: Product with Serializable with Either[Exception,Int] =
      Left(java.lang.NumberFormatException: For input string: "fail")

这篇关于如何获得Scala Future中抛出的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆