Подтвердить что ты не робот

Предпочтителен ли "Умирающий"?

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

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

Как вы думаете?

4b9b3361

Ответ 1

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

Ответ 2

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

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

Это совсем другая идеология из нормы Оборонительное программирование:

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

Мне лично нравится философия "Crash Early, Crash Often".

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

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

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

Ответ 3

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

Ответ 4

Звучит как Guruspeak

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

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

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

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

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

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

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

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

EDIT: Я догадываюсь, что я смутился тем, что подразумевалось под "процессом die" - это ссылка на все приложение или только на поток и т.д.?

Ответ 5

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

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

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

Ответ 6

Это очень микрософт.

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

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

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

Ответ 7

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

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

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

Ответ 8

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

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

Ответ 9

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

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

Ответ 10

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

Ответ 11

Чего ожидает ваш клиент?

Все возвращается к этому. Если клиент может справиться с программой, и они могут перезапустить ее, пусть будет так.

Иногда лучше разрешить процесс умирать и создавать другой для обработки запросов.

Иногда лучше попытаться решить проблему.

Ответ 12

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

Ответ 13

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

Например, если вы пишете торговую систему в режиме реального времени, и там появляется непредвиденная ошибка, вам лучше разрешить ее сбой. В противном случае ваша программа может продолжать идти и делать глупые сделки. Пользователи будут жаловаться сразу "WTF?", Но по крайней мере вы не потеряете миллионы долларов.

Ответ 14

Удивительные ответы здесь уже, особенно Simucal. Я просто хочу добавить точку:

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

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

Иногда вы можете иметь это в обоих направлениях. Я часто писал код C в следующих строках:

void foo(char* data) {
    ASSERT(data);
    if (!data) { return; }
    // ... work with data
}

Если этот код скомпилирован в тестовой среде, оператор assert останавливает условие ошибки. Если он компилируется в производственной среде, утверждение удаляется препроцессором, а foo() терпит неудачу.

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

Ответ 15

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

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

  • Новые службы Windows предоставляют эту функцию при регистрации в MS.
  • Установка drwatson также может захватывать данные (файлы дампов) для ваших пользователей для отправки вам вручную.

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

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

Ответ 16

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

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