Почему хорошие программисты иногда тихо глотают исключения?

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

Другими словами, это плохо, но почему делают хорошие программисты, в редких случаях, используют его?

try
{
    //Some code
}
catch(Exception){}
37
задан IAdapter 29 July 2010 в 11:21
поделиться

16 ответов

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

44
ответ дан 27 November 2019 в 04:11
поделиться

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

-2
ответ дан 27 November 2019 в 04:11
поделиться

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

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

0
ответ дан 27 November 2019 в 04:11
поделиться

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

  Try
    MyControl.BeginInvoke(MyControlUpdateDelegate);
  Catch Ex as Exception
  End Try

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

Обратите внимание, что я мог бы добавить «If Not MyControl.IsDisposed Then ...», но это просто добавит работы к общему случаю и не предотвратит возникновение исключения, если элемент управления будет удален во время BeginInvoke.

0
ответ дан 27 November 2019 в 04:11
поделиться

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

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

Другой пример может быть, когда у вас есть альтернативные средства обработки ситуаций, например:

private Boolean SomeMethod() {
   Boolean isSuccessful = false;
   try {
      // call API function that throws one of several exceptions on failure.
      isSuccessful = true;
   } catch(Exception) { }

   return isSuccessful;
}

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

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

0
ответ дан 27 November 2019 в 04:11
поделиться

Потому что иногда даже хорошие программисты делают ошибки.

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

7
ответ дан 27 November 2019 в 04:11
поделиться

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

После презентации, конечно, никто не станет улучшать эти «быстрые исправления». ; -)

6
ответ дан 27 November 2019 в 04:11
поделиться

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

Например. (в некоторых вымышленных языках, где деление на ноль рассматривается как ошибка):

try {
    x = 1 / (a*a + 1);
} catch (DivisionByZeroException ex) {
  // Cannot happen as a*a+1 is always positive
}

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

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

Edit: На практике я бы добавил assert (false) в блок catch. Если теоретически чего-то не может произойти, то на практике это очень серьезная проблема;)

Edit2: Java требует только перехвата проверенных исключений. Немного переделал свое заявление.

24
ответ дан 27 November 2019 в 04:11
поделиться

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

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

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

По сути, для этого нет никакой другой причины, кроме лени.

1
ответ дан 27 November 2019 в 04:11
поделиться

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

-2
ответ дан 27 November 2019 в 04:11
поделиться

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

-1
ответ дан 27 November 2019 в 04:11
поделиться

Не претендуя на роль хорошего программиста, я могу хотя бы объяснить, почему я иногда ловлю и игнорирую. Бывают случаи, когда то, над чем я работаю, должно иметь дело с исключением для компиляции, но это не подходящее место для фактической обработки исключения. Например, я недавно работал в программе, которая анализирует значительную часть XML как одну из своих задач. Фактический синтаксический анализатор XML открыл файл, который сгенерировал исключение. Однако синтаксический анализатор XML был не лучшим местом для создания диалогового окна, информирующего пользователя о неправильном выборе файла. Вместо того, чтобы отвлекаться на то, чтобы выбросить исключение в нужное место и обработать его там, я тихо перехватил исключение, оставив комментарий и TODO (которые моя IDE отслеживает для меня).Это позволило мне скомпилировать и протестировать без обработки исключения. Иногда я забываю немедленно заняться TODO, и проглоченное исключение остается на некоторое время.

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

1
ответ дан 27 November 2019 в 04:11
поделиться

Я бы сказал, что хороший программист не стал бы этого делать, не объяснив это.

try
{
    //Some code
}
catch(Exception e) {
    // Explanation of why the exception is being swallowed.
}

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


Вот конкретный пример, который я случайно встретил сегодня в своем проекте. Это часть функции JavaScript, которая получает XMLHttpRequest , поддерживаемый браузером.

var XMLHttp = null;

if( window.XMLHttpRequest ) {
    try {
        XMLHttp = new XMLHttpRequest();
    } catch(e) {} // we've already checked that this is safe. 
}
else if( window.ActiveXObject ) {
...
}

Поскольку try заключен в if ... else if , который проверяет тип создаваемого объекта, можно безопасно проглотить исключение.

15
ответ дан 27 November 2019 в 04:11
поделиться

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

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

  2. Более оправдано: внутренняя обработка ошибок. Если мне не удастся записать в файл журнала, где я буду записывать ошибку, в которой говорится, что я не могу записать ошибку? В некоторых случаях вы можете попытаться написать на экран, но в зависимости от приложения это может быть невозможно, например фоновая работа без экрана; или просто сбивает с толку пользователя, который все равно ничего не сможет сделать с ошибкой.

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

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

Дополнительное примечание: почему программисты обычно включают комментарии типа «x = x + 1; // добавить 1 к x», например, да, я бы никогда не придумал это без комментария, но затем добавляю действительно загадочные код без объяснения?

Добавление через четыре года после моего первоначального сообщения

Конечно, НАСТОЯЩАЯ причина, по которой даже хорошие программисты иногда проглатывают исключения, заключается в следующем: «Я пытаюсь заставить работать базовую логику, я не уверен, что делать, если это исключение случается, я не хочу связываться с этим прямо сейчас,У меня слишком много проблем с нормальным логическим потоком, но я вернусь к нему позже ». А потом они забывают вернуться к нему.

Кстати, плохая причина, которую я слышал от нескольких людей, которых я обычно Думаю, что это довольно хорошие программисты: «Я не хочу показывать пользователю загадочное сообщение об ошибке. Это бы их просто сбило с толку. Лучше молча проглотить ошибку ». Это плохая причина, потому что (а) вы все еще можете записать что-то в файл журнала. И (б) действительно ли загадочное сообщение об ошибке хуже, чем создание у пользователя впечатления, что операция выполнена успешно нет? Теперь клиент думает, что его заказ обрабатывается, хотя на самом деле это не так, или он думает, что скорая помощь отправлена, чтобы помочь своему ребенку, который кричит от боли, но на самом деле сообщение никогда не было доставлено и т. д. в самых тривиальных случаях, если на форуме не было пустого поста или что-то в этом роде, я бы предпочел получить загадочное сообщение, которое, по крайней мере, дает мне представление о том, что что-то пошло не так, и если мне не все равно, я должен попробовать еще раз или позвонить кому-нибудь, тогда просто скажите «обновление завершено», когда на самом деле это не так.

9
ответ дан 27 November 2019 в 04:11
поделиться

по крайней мере записать его в окно вывода

try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}
0
ответ дан 27 November 2019 в 04:11
поделиться

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

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

5
ответ дан 27 November 2019 в 04:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: