Сначала я быстро мотивирую вопрос в своем случае использования. Моя библиотека должна подвергать классификатор исключений 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.
Я планирую использовать идентификатор хэш-набора, чтобы обнаружить цикл и снизить риск, но я хотел услышать, как другие видят Эта проблема. Вы думаете, что я слишком защищаюсь? Что бы вы сделали?