Предпочтительнее ли умирать? - PullRequest
18 голосов
/ 23 февраля 2009

Недавно я посещал учебные курсы Джеффри Рихтера по .NET. Он упоминает одну стратегию кодирования: «Умереть - это круто». То есть не пишите «catch (Exception ex)» даже в корне программы или цикла обработки событий. Если выдается какое-то исключение, которое не обрабатывается, просто дайте процессу умереть.

Я не уверен, что это правильно. Лично я предпочитаю иметь «try {...} catch(Exception ex) {log and try to recover}» для переноса на верхнем уровне исполнения. На самом деле, ASP.NET не умирает, если любое исключение выбрасывается из asXx. Если он умрет за исключение, то один запрос с применением серебряной пули может заставить замолчать весь сервис.

Что ты думаешь?

Ответы [ 16 ]

37 голосов
/ 23 февраля 2009

Я думаю, это зависит от того, какое приложение вы используете и каковы последствия «умирания». Для многих клиентских приложений умирать - это круто. Для серверов часто не так много (и swallow-and-log подходит). Единого универсального решения не существует.

22 голосов
/ 23 февраля 2009

Также известен как наступательное программирование.

Вы должны проверить: " Наступательное программирование: ранний крах, частый крах ".

Это очень отличная идеология от нормы Защитное программирование :

[Защитное программирование] предназначено для обеспечить постоянную функцию часть программного обеспечения, несмотря на непредвиденное использование указанного программного обеспечения.

Мне лично нравится философия «Crash Early, Crash Часто».

Я видел слишком много:

try  
{  
    // ... Huge block of code goes here  
}  
catch(Exception ex)  
{  
   // Do nothing...  
}  

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

8 голосов
/ 25 февраля 2009

Карл Сегуин говорит следующее об обработке исключений:

  1. Обрабатывать только те исключения, которые вы действительно можете сделать с
  2. Вы ничего не можете сделать с подавляющим большинством исключений

Хорошее введение в тему.

8 голосов
/ 23 февраля 2009

Похоже на Guruspeak

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

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

Что бы вы подумали о следующих приложениях, умирающих при обычном исключении:

  • Медицинские приборы
  • Электростанции
  • Системы обнаружения вторжений

За исключениями, которые вы ловите в try / catch - вы действительно должны ожидать их и обрабатывать их. Для всех остальных случаев хорошо быстро провалиться до прогнозируемого уровня выполнения. Итак, если вы работаете с сетевым или веб-обработчиком, почему бы просто не умереть текущей операции? Вы действительно нуждаетесь в целом приложении, чтобы выйти из строя?

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

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

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

РЕДАКТИРОВАТЬ: я думаю, меня смутило то, что подразумевалось под "process die" - это была ссылка на все приложение или только на запущенный поток и т. Д.?

8 голосов
/ 23 февраля 2009

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

6 голосов
/ 23 февраля 2009

Это очень Microsoft.

MS хочет, чтобы вы выбросили все необработанные исключения в WER. (Отчет об ошибках Windows, это диалоговое окно, которое вы получаете, чтобы отправить ошибку в Microsoft при сбое приложения)

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

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

3 голосов
/ 23 февраля 2009

Если вы не можете адекватно решить проблему - и если это что-то кроме отклонения неверного ввода в какой-либо форме (это включает в себя что-то, что вы пытались прочитать с диска или из Интернета), вы, вероятно, не можете - тогда вам следует умереть. Если вы не уверены на 100%, что можете продолжать безопасно, не надо.

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

3 голосов
/ 23 февраля 2009

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

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

Опять же, я продаю продукт именно для этой цели, поэтому я немного предвзят в этой области!

2 голосов
/ 23 февраля 2009

Поскольку вы не знаете, что такое каждый подкласс исключения, вы просто НЕ МОЖЕТЕ знать, что можно ловить их. Поэтому вам следует заняться собственным делом: ловить известные вам и волнующие исключения, которые в основном будут теми, которые вы явно создали для своей собственной программы, или теми, которые созданы для ошибок из-за используемых вами вызовов библиотеки. В частности, поймать класс Exception - это просто лень, плохое программирование - по сути, вы говорите: «Мне все равно, в чем проблема, и не говорите мне, просто сделайте это». Посмотрите, как java-программы обрабатывают исключения, так как практика обработки исключений там, как правило, довольно хорошая.

2 голосов
/ 23 февраля 2009

Ничто так не разрушает доверие пользователей, как трассировка стека. Как минимум, поймайте исключение и запишите как можно больше информации. Затем предоставьте пользователю дружественное сообщение и инструкции о том, что нужно сделать, чтобы обойти проблему или сообщить о проблеме в службу поддержки.

Здесь есть беспокойство относительно продолжения в неопределенном состоянии. Если это веб-приложение, то это не проблема, если вы не слишком зависимы от сеанса и состояния приложения. Если это приложение для Windows, не стесняйтесь выйти (после того, как у пользователя будет возможность сохранить).

...