Основной метод кода полностью внутри try / catch: это плохая практика? - PullRequest
31 голосов
/ 28 января 2011

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

public static void Main(string[] args)
{
   try
   {
      // code
   }
   catch (Exception e)
   {
      // code
   }
}

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

Как вы думаете, это плохая практика?

Ответы [ 5 ]

39 голосов
/ 28 января 2011

Упаковка любого фрагмента кода в блоке try / catch без веской причины - плохая практика.

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

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

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


РЕДАКТИРОВАТЬ: Когда я начал читать превосходный блог Рэймонда Чена, "The Old New Thing" , я заметил, что он недавно опубликовал статью опохожая тема.Он специфичен для COM, а не для .NET Framework, но общие концепции обработки ошибок одинаково применимы к обеим средам.Я думал, что я разделю несколько драгоценных камней из статьи здесь, в поддержку моего [по-видимому, весьма спорным] мнение.

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

Имейте в виду, это фактически было медвежьей услугой.

Тот факт, что произошло необработанное исключение, означает, что сервер находился в непредвиденном состоянии.Перехватывая исключение и говоря: «Не волнуйтесь, все хорошо», вы в конечном итоге оставляете поврежденный сервер включенным.

[.,,]

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

Гораздо лучше позволить серверу дать сбой, чтобы аварийный дамп мог быть захвачен в момент сбоя.Теперь у вас есть реальный шанс выяснить, что происходит.

Вы можете [и должны] прочитать всю статью здесь в его блоге: Как отключить обработчик исключений этого COM "Полезно "обвивает ваш сервер .

6 голосов
/ 28 января 2011

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

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

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

4 голосов
/ 17 октября 2012

Я согласен с 90% того, что говорит Коди.Есть некоторые ситуации, подобные примеру плагина, когда вы можете захотеть перехватить системные исключения.Вот еще один пример использования веб-службы WCF .

Цель : использование службы и ее устранение даже в случае возникновения ошибки.Разрешить ошибку пузыриться.

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        throw;//This service is critical to application function. The application should break if an exception is thrown.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}

Цель : использовать службу и утилизировать ее даже в случае возникновения ошибки.Предотвратите ошибку от пузырей.

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        //throw; //This service is auxiliary to the applications primary function. We have no influence over the service and therefore cannot fix it.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}
1 голос
/ 28 января 2011

Определенно, да, это плохая практика, использовать исключительный класс

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

Класс исключений является базовым классом, и исключение верхнего уровня может быть перехвачено в коде. Используйте наиболее конкретные исключения в блоке catch, в частности, единственное, которое вы кодируете, возникает в блоке try {...} catch {...}, и только если оно может быть эффективно разрешено на этом конкретном уровне функция, где попробуй .. блок catch объявлен)

0 голосов
/ 28 января 2011

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

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

...