捕获嵌套到另一个异常中的异常

我想捕获一个异常,该异常嵌套到另一个异常中。我目前以这种方式进行:

} catch (RemoteAccessException e) {
    if (e != null && e.getCause() != null && e.getCause().getCause() != null) {
        MyException etrp = (MyException) e.getCause().getCause();
        ...
    } else {
        throw new IllegalStateException("Error at calling service 'service'");
    }
}

有没有办法做到这一点更有效和优雅?


答案 1

ExceptionUtils#getRootCause() 方法在这种情况下可以非常方便。


答案 2

没有比这更优雅的方法来选择性地“捕获”嵌套异常。我想如果你做了这种嵌套的异常捕获很多,你可能会把代码重构成一个通用的实用程序方法。但它仍然不会既优雅也不高效。

优雅的解决方案是取消例外嵌套。要么不要首先链接异常,要么(有选择地)解包并重新抛出嵌套的异常,使其在堆栈中进一步向上。

异常倾向于嵌套,原因有 3 个:

  1. 您已经确定原始异常的详细信息不太可能对应用程序的错误恢复有用...但您希望保留它们以用于诊断目的。

  2. 您正在实现的 API 方法不允许特定的已检查异常,但您的代码不可避免地会引发该异常。一种常见的解决方法是将选中的异常“走私”到未选中的异常中。

  3. 您很懒惰,将一组相关的异常转换为单个异常,以避免在方法签名1 中出现大量已检查的异常。

在第一种情况下,如果您现在需要对包装的异常进行区分,那么您最初的假设是不正确的。最好的解决方案是更改方法签名,以便您可以摆脱嵌套。

在第二种情况下,一旦控件通过有问题的 API 方法,您可能应该立即解开异常的包装。

在第三种情况下,您应该重新考虑您的异常处理策略;即正确操作2.


1 - 事实上,由于在Java 7中引入了多异常捕获语法,这样做的半合法原因之一已经消失了。

2 - 不要将 API 方法更改为引发异常。这只会让事情变得更糟。现在,每次调用方法时都必须“处理”或传播 Exception。这是一种癌症...