我正在使用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]
而不更改{我想得到编译错误{1}},当转换为ErrorOccurredDuringFoo
失败时,不是运行时错误。
答案 0 :(得分:4)
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]
的别名。
作为案例陈述是 PartialFunction
,我们可以使用模式匹配:
val c: Catcher[Foo] = {
case e: MyException => throw new ErrorOccurredDuringFoo(e)
}
catching(c)(fooInternals)
答案 1 :(得分:1)
你可以这样写:
def foo : Foo = {
catching(classOf[Exception]) either { fooInternals } match {
case Left(e: Exception) => throw ErrorOccurredDuringFoo(e)
case Right(v) => v
}
}
有趣的是,它不会抱怨遗失的案件。