我正在使用 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/

10-10 20:16