Try Catches все еще полезны? - PullRequest
9 голосов
/ 13 апреля 2009

Когда я впервые начал программировать в .NET, я все время использовал try / catch. Я нахожу в последнее время, хотя я редко использую их для веб-приложений. Мое исключение (без каламбура) - неуправляемый код, который потенциально может создать утечку памяти, такую ​​как com-объекты. Они действительно нужны больше или они просто загромождают вещи?

ОБНОВЛЕНИЕ: Предположим, что пользовательские ошибки используются для обработки страницы трассировки уродливого стека.

Ответы [ 8 ]

22 голосов
/ 13 апреля 2009

Я считаю, что младшие программисты слишком часто используют try / catch WAY. Решение использовать try / catch должно сводиться к следующим простым правилам:

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

  • Можете ли вы предоставить лучшее сообщение об ошибке (более подробно)?

  • нужно ли регистрировать эту конкретную ошибку? (имейте в виду, что все ошибки должны регистрироваться на самом высоком уровне - например, в файле global.asax в методе Application_Error)

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

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

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

только что нашел эту превосходную цитату из Ayende , которая, кажется, очень красиво выразилась:

Обработка исключений должна появиться в ровно в двух местах:

  • Когда ожидается ошибка (например, вызов по веб-запросу) и есть какое-то осмысленное поведение быть сделано в случае отказа (такой как повторная попытка после некоторой задержки)
  • На границе системы, в этом случае вам нужно принять решение о том, как вы собираетесь выставить ошибку внешний мир.
18 голосов
/ 13 апреля 2009

Вот ответ в виде вопроса

Как вы собираетесь обрабатывать ошибки, если не перехватываете исключения?

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

3 голосов
/ 13 апреля 2009

использование Finally

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

И, хотя это правда, что вы должны избегать попыток перехвата, когда они не нужны (например, проверьте if x == null вместо того, чтобы позволять x throw NullReferenceException). Вы обнаружите, что особенно в веб-приложениях есть тонны В некоторых случаях операторы try-catch были абсолютно необходимы, потому что иногда вы теряете соединения, или пользователь поступит неправильно, и будут выброшены исключения, нравится вам это или нет.

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

3 голосов
/ 13 апреля 2009

Попытки отлова являются важным аспектом программирования и не должны игнорироваться; однако вам не нужно заключать каждый оператор в блок try catch. Обычно я использую следующие правила:

  1. Если это приложение для Windows, то для точки входа всегда должна быть попытка перехвата в качестве последней попытки разрыва для обнаружения любых исключений. В asp.net это делается с помощью OnError объектов Application.

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

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

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

  5. Если есть ресурсы, которые необходимо очистить, то я использую команду try catch или блок finally, чтобы убедиться, что мои ресурсы закрыты.

2 голосов
/ 13 апреля 2009

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

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

0 голосов
/ 14 апреля 2009

Используйте Catch (SomeException ex), только если вы готовы обработать SomeException. Исключения, которые вы не хотите обрабатывать, считаются неожиданными. Используйте модульные тесты, чтобы проверить свой код и найти ожидаемые исключения.

Следующий пример неверен, потому что вы ничего не делаете, за исключением

try
{
    // Some code that throws a exception
}
catch(Exception ex)  // Only handle this type of exception in the User interface.
{
    throw;     // Incorrect, throwing exception for no reason
}

Это лучше:

try
{
    // Some code that throws a exception
}
catch(System.Data.UpdateException ex)
{
    LogException(ex);
    string message = DecipherException(ex);
    throw new MyException(message, ex);     // Incorrect
}

И продолжить (в пользовательском интерфейсе)

try
{
    // Code that throws a exception
}
catch (MyException myEx)
{
   // Use a nice dialog which shows the user how to fix the error
}
catch (Exception ex)
{
    // Unhandled scenario - usually fatal because you didn't expect it to happen.
}
0 голосов
/ 14 апреля 2009

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

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

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

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

0 голосов
/ 13 апреля 2009

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

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