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

Почему бы не поймать общие исключения

Мой VS просто сказал мне:

Предупреждение 2 CA1031: Microsoft.Design: Изменить "Program.Main(string [])", чтобы поймать более конкретное исключение, чем "Исключение" или перестроить исключение.

Зачем мне это делать? Если я это сделаю и не поймаю все исключения, чтобы справиться с ними, моя программа выйдет из строя с помощью всенародного экрана отчета. Я не хочу, чтобы мои пользователи получали такую ​​ошибку-дерьмо!

Почему я не должен сразу перехватывать все исключения, чтобы показать приятное предупреждение пользователю: "Что-то пошло не так, меня это не волнует, я буду справляться с этим, просто быть терпеливым"?

Изменить: просто увидел, что у меня есть обман, извините за Dupe

Edit2. Чтобы прояснить ситуацию; Я выхожу из программы после того, как все исключения были пойманы! Я просто не хочу, чтобы мой пользователь увидел этот диалог "report to microsoft", который появляется, когда необработанное исключение возникает в консольном приложении!

4b9b3361

Ответ 1

Глотание исключений - опасная практика, потому что:

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

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

Лучшая практика

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

По возможности обрабатывайте ожидаемые исключения на гранулированном уровне (например: FileNotFoundException).

Для неожиданных исключений вы можете сделать одну из двух вещей:

  • Пусть они пузырятся нормально и вызывают сбой
  • Поймать их и изящно выйти из строя

Неудачный сбой?

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

В наших приложениях мы обычно улавливаем необработанные исключения в global.asax, а затем выполняем ведение журнала и отправку уведомлений по электронной почте. Мы также показываем более дружественную страницу ошибок, которую можно настроить в web.config с помощью тега customErrors.

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

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

Другие заметки

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

Ответ 2

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

EDIT: Чтобы прояснить различия между компонентами пользовательского интерфейса и компонентами службы или промежуточного программного обеспечения.

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

Для Main(), я бы рассмотрел два случая:

  • Ваша собственная (отладочная) сборка, где вы хотите получить всю информацию об исключении, которую вы можете получить: не поймайте никаких Исключений здесь, поэтому отладчик разбивается, и у вас есть стек вызовов,
  • Ваши общедоступные релизы, в которых вы хотите, чтобы приложение нормально себя ведет: Catch Exception и отображение хорошего сообщения. Это всегда лучше (для обычного пользователя), чем окно "отправить отчет".

Чтобы сделать это, просто проверьте, определен ли DEBUG (и определите его, если VS не делает это автоматически):

#if DEBUG
  yadda(); // Check only specific Exception types here
#else
  try
  {
    yadda();
  }
  catch (Exception e)
  {
     ShowMessage(e); // Show friendly message to user
  }
#endif

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

Ответ 7

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

MSDN SuppressMessageAttribute

Ответ 8

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

Ответ 9

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

Ответ 10

В VS вы можете настроить страницу пользовательских ошибок, чтобы показать своим пользователям, когда что-то пойдет не так, а не поймать его в попытке. Я предполагаю, что вы используете VS, используя ASP.NET. Если так, добавьте этот тег в свой Web.Config под тегом System.Web:

<customErrors mode="RemoteOnly" defaultRedirect="~/CustomErrorPage.aspx" redirectMode="ResponseRewrite" />

Вы также можете поймать все неперехваченные исключения в файле Global.asax(если у вас его еще нет: щелкните правой кнопкой мыши веб-проект, выберите "Добавить элемент" и найдите его). В этом файле есть куча обработчиков событий, таких как "Application_Error", которые захватывают все исключения, которые не попадают в ваше приложение, поэтому вам не нужно постоянно использовать Try-Catch. Это полезно использовать для отправки электронной почты, если возникает исключение, и, возможно, перенаправить их на главную страницу или что-то еще, если вы не хотите использовать тег customErrors выше.

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

Ответ 11

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

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

Следовательно, отключите (снимите флажок) предупреждение с помощью настроек проекта, как указано в Microsoft.CodeQuality.Analyzers. Это можно найти в настройках проекта в Code Analysis:

enter image description here