Где обрабатывать фатальные исключения - PullRequest
3 голосов
/ 11 апреля 2010

Я рассматриваю проект, в котором все фатальные исключения будут обрабатываться с помощью пользовательского UncaughtExceptionHandler в приложении Swing. Это будет включать непредвиденные исключения RuntimeException, но также и пользовательские исключения, которые генерируются, когда критически важные ресурсы недоступны или иным образом возникают сбои (например, файл настроек не найден или ошибка связи с сервером). UncaughtExceptionHandler будет делать разные вещи в зависимости от конкретного пользовательского исключения (и одна вещь для всех непредвиденных), но во всех случаях приложение покажет пользователю сообщение об ошибке и завершит работу. Альтернативой может быть сохранение UncaughtExceptionHandler для всех непредвиденных исключений, но обработка всех других фатальных сценариев, близких к их источнику.

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

Ответы [ 4 ]

2 голосов
/ 11 апреля 2010

Как правило, трудно найти хорошую стратегию обработки исключений. У каждого подхода есть свои недостатки. В частности, Yours хорош в некотором смысле (централизованное расположение для обработки сбоев), но страдает этим недостатком:

Обработчик исключений, который вы описываете, будет иметь специальную обработку для каждого возможного исключения. Со временем это станет фокусом вашего приложения: каждый раз, когда вы добавляете новые функции, вам также нужно будет добавлять логику обработки исключений в ваш обработчик. Это означает, что:

  1. Обработчик сильно зависит от других частей, изменение в impl. некоторые функции могут вызывать соответствующие изменения в обработчике. Вы должны быть осторожны в синхронизации этих двух.
  2. У обработчика плохая связность (есть много причин для изменения) - он содержит пересечение всех функций вашего приложения.

Другая проблема - восстановление после ошибок. После того, как выдается исключение (и пользователю предоставляется некоторое уведомление), пользователь хочет продолжить использование приложения. Это означает, что если ваш код начал изменять внутренние структуры данных, а затем остановился из-за исключения, вам нужно будет отменить эти изменения (или, по крайней мере, вернуть структуру данных в работоспособное состояние), прежде чем разрешить дополнительное взаимодействие с пользователем. Достижение этого требует нового понимания того, как организованы ваши данные. Одним из возможных решений является транзакции с БД. С другой стороны, этот вид представления более сложен, чем простые старые структуры данных, поэтому вам необходимо сопоставить его с потребностями вашего приложения (это игрушка / прототип?)

1 голос
/ 11 апреля 2010

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

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

Любые неперехваченные исключения обрабатывались как «общая ошибка» или что-то подобное. Работало хорошо, и, конечно, мы пытались выпустить код, который не вызывал необработанных исключений. Тем не менее, это была очень полезная функция при тестировании.

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

0 голосов
/ 11 апреля 2010

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

0 голосов
/ 11 апреля 2010

Было бы проще обернуть логику метода main в блок try catch; например,

public static void main(String[] args) {
    try {
        // everything happens here
        System.exit(0);
    } catch (SpecificException ex) {
        ...
    } catch (AnotherException ex) {
        ...
    } catch (Throwable ex) {
        // deal with anything else.
        ...
    }
    System.exit(1);  // tell the world that we failed.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...