链式异常中的循环

Bri*_*ris 12 java guava

我将首先用我的用例快速激发问题.我的库需要将Java异常分类器暴露给它插入的框架.例如:

enum Classification { FATAL, TRANSIENT, UNKNOWN }

Classification classify(Throwable t) {
    if (t instanceof MyTransientException)
        return Classification.TRANSIENT;
    else if (t instanceof MyFatalException)
        return Classification.FATAL;
    else
        return Classification.UNKNOWN;
}
Run Code Online (Sandbox Code Playgroud)

有时,由于我无法控制的原因,传递的异常是我感兴趣的一个包装器所以我想搜索它的原因链.我最初的想法是:

Classification classify(Throwable t) {
    if (t == null)
        return Classification.UNKNOWN;

    if (t instanceof MyTransientException)
        return Classification.TRANSIENT;
    else if (t instanceof MyFatalException)
        return Classification.FATAL;
    else
        return classify(t.getCause());
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果传递的异常在其因果链中有一个循环,这可能导致无限递归.这样的异常很可能不会被传递,并且如果创建了这样的异常,可能会在系统的其他地方出现错误,但我对我的库负责生产的可能性感到非常不舒服如果发生中断.Throwable的API和javadoc没有明确禁止这种可能性,因为循环在因果链中本质上是无意义的.

我注意到Guava有一个@Beta方法来提取因果链Throwables.getCausalChain,但它的实现容易受到同样的问题 - 它最终会抛出一个OOME.

我打算使用身份哈希集来检测周期并降低风险,但我想听听别人如何看待这个问题.你觉得我过度防守吗?你会怎么做?

Kev*_*ion 14

你是如此认真,这很好.但是你不想进入制造凯夫拉靴的生意.

如果用户做了一些甚至Throwable.printStackTrace会进行无限递归的事情,那么该用户就无法帮助了.甚至不担心这个.