Обрабатывание нескольких исключений

Я записал класс, который загружает объекты конфигурации моего приложения и отслеживает их так, чтобы я мог легко выписать изменения или перезагрузить целую конфигурацию сразу с вызовом отдельного метода. Однако каждый объект конфигурации мог бы потенциально выдать исключение при выполнении IO, все же я не хочу тех ошибок отменить полный процесс, чтобы дать другим объектам все еще шанс перезагружать/писать. Поэтому я собираю все исключения, которые выдаются при итерации по объектам и хранят их в суперисключении, которое брошено после цикла, так как должно все еще быть обработано каждое исключение, и кто-то должен быть уведомлен относительно того, что точно пошло не так, как надо. Однако тот подход выглядит немного нечетным мне. Кто-то там с более чистым решением?

Вот некоторый код упомянутого класса:

public synchronized void store() throws MultipleCauseException
    {
    MultipleCauseException me = new MultipleCauseException("unable to store some resources");
    for(Resource resource : this.resources.values())
        {
        try
            {
            resource.store();
            }
        catch(StoreException e)
            {
            me.addCause(e);
            }
        }
    if(me.hasCauses())
        throw me;
    }
8
задан the-banana-king 15 March 2010 в 01:34
поделиться

2 ответа

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

Я предлагаю передавать исключения или данные, полученные из них, в обратный вызов обработки ошибок по мере продвижения.

public interface StoreExceptionHandler {
    void handle(StoreException exc);
}

public synchronized void store(StoreExceptionHandler excHandler) {
    for (Resource resource : this.resources.values()) {
        try {
            resource.store();
        } catch (StoreException exc) {
            excHandler.handle(exc);
        }
    }
    /* ... return normally ... */
]
4
ответ дан 5 December 2019 в 21:17
поделиться

Существуют руководящие принципы при разработке того, какие исключения должны генерироваться и когда, и два важных для этого сценария:

  • Выбрасывать исключения, соответствующие абстракции (то есть парадигме преобразования исключений)
  • Выбрасывать исключения раньше, если возможно

То, как вы переводите StoreException в MultipleCauseException , мне кажется разумным, хотя объединение разных типов исключений в один - не лучшая идея. К сожалению, Java не поддерживает общие Throwable , поэтому, возможно, единственной альтернативой является создание вместо этого отдельного подкласса MultipleStoreException .

Что касается создания исключений как можно раньше (чего вы НЕ делаете), я скажу, что в некоторых случаях можно изменить правило. Я чувствую, что опасность откладывать бросок возникает тогда, когда исключительные ситуации без надобности превращаются в цепную реакцию. По возможности вы хотите избежать этого и локализовать исключение в минимально возможной области.

В вашем случае, если имеет смысл концептуально рассматривать хранение ресурсов как несколько независимых задач , тогда может быть приемлемым «пакетную обработку» исключения, как вы это сделали. Однако в других ситуациях, когда задачи имеют более сложные отношения взаимозависимости, их объединение в одну кучу усложняет задачу анализа исключений.

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

3
ответ дан 5 December 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: