我正在使用 util.control.Exception.catching
将内部异常转换为特定于我的库的异常类型:
import util.control.Exception._
abstract class MyException extends Exception
case class ErrorOccurredDuringFoo(e : Exception) extends MyException
def foo : Foo = {
catching(classOf[Exception]) either { fooInternals } match {
case Left(e) => throw ErrorOccurredDuringFoo(e)
case Right(v) => v
}
}
不幸的是,这行不通。应用
Catch
返回的 either
不会返回 Either[Exception,Foo]
,而是返回 Either[Throwable,Foo]
。但是我已经告诉 catching
我希望它只捕获 Exception
的子类型,而不是所有 Throwable
,并且在内部它已经匹配了 Exception
。我正确使用它吗?我有没有办法说服
catching
返回它捕获的异常作为我要求它捕获的异常类的实例?我最好的选择是添加一个冗余的 asInstanceOf[Exception]
吗?如果我可以避免它,我宁愿不这样做,因为 catching
实例可以在逻辑上在其他地方创建,如果有一天我将它更改为 catching[Throwable]
而不更改 ErrorOccurredDuringFoo
,我希望得到一个编译错误,而不是转换时的运行时错误Exception
失败。 最佳答案
Catch
不在 Throwable
上参数化,仅在结果类型上。向下转换 Throwable 类型的唯一方法是使用 mkCatcher 方法:
val c = catching[Foo](
mkCatcher(
(t: Throwable) => t.getClass == classOf[MyException],
(e: MyException) => throw new ErrorOccurredDuringFoo(e)))
c(fooInternals)
但是,
Catch
需要一个 Catcher[T]
- 这实际上只是 PartialFunction[Throwable, T]
的别名。由于 case 语句是
PartialFunction
,我们可以使用模式匹配:val c: Catcher[Foo] = {
case e: MyException => throw new ErrorOccurredDuringFoo(e)
}
catching(c)(fooInternals)
关于exception - 使用 catch(...).either 时,我可以避免多余地转换 Throwable 吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7396297/