Как реализовать обработку исключений верхнего уровня?
-
03-07-2019 - |
Вопрос
Недавно мне пришлось разработать дополнительный модуль для существующего сервиса, разработанный коллегой. Он поместил блок try / catch в основную рабочую функцию для перехвата всех неэкранированных исключений, которые доходили до этого уровня, регистрируя их вместе с информацией трассировки стека и т. Д.
try
{
// do main work
}
catch(Exception ex)
{
// log exception info
}
Несмотря на то, что это делает программу очень стабильной (как в случае «вероятности сбоя»), я ненавижу ее, потому что, когда я тестирую свой код, я не вижу исключений, вызванных этим. Конечно, я могу просмотреть журнал исключений и посмотреть, есть ли новые записи, но я очень предпочитаю прямую обратную связь о получении исключения в момент его создания (с курсором на правой строке в коде, пожалуйста). р>
Я удалил этот верхний уровень try / catch хотя бы во время кодирования и тестирования. Но теперь моя задача закончена, и я должен решить, стоит ли возвращать ее для релиза или нет.
Я думаю, что должен сделать это, потому что это делает сервис более стабильным, и весь смысл в том, что он работает в фоновом режиме, не требуя никакого контроля. С другой стороны, я прочитал, что нужно вызывать только определенные исключения (как в IoException
), а не в общем Exception
.
Что вы посоветуете по этому вопросу?
Кстати, проект написан на C #, но меня также интересуют ответы на языки, отличные от .NET.
Решение
Положи обратно. Р>
Исключение должно относиться только к тестированию. В противном случае это не имеет смысла, поп его пользователю. Р>
Ведение журнала в порядке. Р>
Вы можете дополнительно использовать символ DEBUG, определенный Visual Studio, для отладочных сборок в качестве флага.
...
} catch( Exception e ) {
#if DEBUG
throw;
#else
log as usual
#endif
}
Поэтому в следующий раз, когда потребуется модификация, флаг отладки должен быть установлен в true, и появится всплывающее исключение.
Другие советы
В любом приложении Java вы почти всегда хотите определить обработчик исключений для неперехваченных исключений, например:
Thread.setDefaultUncaughtExceptionHandler( ... );
где объект, который перехватит эти неперехваченные исключения, по крайней мере зарегистрирует ошибку, чтобы у вас была возможность узнать об этом. В противном случае, нет никакой гарантии, что вы даже будете уведомлены о том, что поток принял исключение - если только это не ваш основной поток.
В дополнение к этому, в большинстве моих потоков есть попытка / отлов, где я буду ловить RunnableException
(но не Error
) и регистрировать его ... некоторые Потоки умирают, когда это происходит, другие будут регистрироваться и игнорироваться, другие будут отображать жалобу пользователю и позволять пользователю решать, в зависимости от потребностей Приложения. Этот try / catch находится в самом корне потока, в методе Runnable.run ()
или его эквиваленте. Так как try / catch находится в корне потока, нет необходимости иногда отключать этот catch.
Когда я пишу на C #, я пишу аналогично. Но все это зависит от необходимости применения. Это исключение, которое будет повреждать данные? Ну, тогда не поймите и не игнорируйте это. ВСЕГДА регистрируйте его, но затем дайте приложению умереть. Однако большинство исключений не относятся к этому типу.
В идеале вы хотите обработать исключение как можно ближе к тому месту, где оно произошло, но это не означает, что глобальный обработчик исключений - плохая идея. Особенно для службы, которая должна работать любой ценой. Я бы продолжил то, что вы делали. Отключите его во время отладки, но оставьте его на месте для производства.
Имейте в виду, что его следует использовать в качестве защитной сетки. Тем не менее, попытайтесь поймать все исключения, прежде чем они подняться так далеко.
Стремление перехватить все исключения и сделать программу «стабильной» очень сильное, и идея кажется очень привлекательной для всех. Проблема, как вы указываете, заключается в том, что это всего лишь уловка, и программа вполне может быть с ошибками и хуже, без признаков сбоев. Никто не контролирует журналы регулярно.
Мой совет - попытаться убедить другого разработчика провести обширное тестирование, а затем развернуть его в рабочей среде без внешнего улова.
Если вы хотите увидеть исключение при его возникновении, в Visual Studio вы можете перейти в меню DEBUG, выбрать EXCEPTIONS, и вы можете указать отладчику прервать работу, как только будет сгенерировано исключение. Вы даже можете выбрать тип исключений. :) Р>