Обработка нескольких исключений - PullRequest
8 голосов
/ 15 марта 2010

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

Вот код указанного класса:

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

Ответы [ 2 ]

4 голосов
/ 15 марта 2010

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

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

3 голосов
/ 15 марта 2010

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...