Циклы в цепных исключениях

Сначала я быстро мотивирую вопрос в своем случае использования. Моя библиотека должна подвергать классификатор исключений 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;
}

Иногда, и по причинам, не зависящим от моего контроля, прошедшее исключение является оберткой вокруг той, которая мне интересна, поэтому я хочу искать цепочку причин для нее. Моя первоначальная идея:

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());
}

К сожалению, это может привести к бесконечной рекурсии, если прошедшее исключение имеет цикл в своей причинно-следственной цепочке. Очень маловероятно, что такое исключение будет передано, и можно было бы аргументировать, что это ошибка в другом месте системы, если такое исключение создано, но мне очень неудобно иметь возможность того, что моя библиотека отвечает за производство если это произойдет. Throwable API и javadoc явно не запрещают эту возможность за пределами идеи, что циклы по своей сути являются бессмысленными в каузальной цепочке.

Я заметил, что у Guava есть метод @Beta для извлечения причинно-следственной цепочки, Throwables.getCausalChain, но его реализация восприимчива к тому же вопрос - это приведет к выбросу OOME.

Я планирую использовать идентификатор хэш-набора, чтобы обнаружить цикл и снизить риск, но я хотел услышать, как другие видят Эта проблема. Вы думаете, что я слишком защищаюсь? Что бы вы сделали?

Ответ 1

Хорошо, что вы так добросовестны. Но вы не хотите заниматься бизнесом изготовления кевларовых сапог.

Если пользователь делает что-то, что сделает даже Throwable.printStackTrace переходить в бесконечную рекурсию, этот пользователь не поддается. Даже не беспокойтесь об этом.