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

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

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

Другими словами, это плохо, но почему хорошие программисты, в редких случаях, используют его?
try
{
    //Some code
}
catch(Exception){}
4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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, который проверяет тип объекта, который будет создан, он безопасно проглатывает исключение.

Ответ 4

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

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

Ответ 5

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

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

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

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

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

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

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

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

Я верю в это из-за проверенных Java исключений. Я лично ненавижу их из-за этого, потому что люди склонны думать, что им нужен код обработки исключений повсюду. IMO в 99% кода вы должны просто бросать свое исключение в стек и не обрабатывать его. Я был бы рад, если бы подпись по умолчанию для любого нового созданного метода имела бы "throws Exception" в нем, так что мне не нужно иметь дело с исключениями, если я этого не хочу.

IMO вам нужно только обработку исключений в двух местах:  1. Для очистки ресурсов, например, закрытие входного потока, подключение к базе данных или удаление файла.  2. На самом верху стека вы поймаете исключение и зарегистрируете его или покажете его пользователю.

Есть места, где вам действительно не нужно ничего делать в catch, например, обрабатывать InterruptedException из Thread.sleep(), и там вы должны хотя бы иметь комментарий, чтобы было ясно, что вы действительно не хотите что-то там произойдет.

Ответ 9

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

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

Ответ 10

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

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

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

В принципе нет веских оснований для этого, кроме ленивости.

Ответ 11

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

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

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

Ответ 12

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

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

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

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.

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

Ответ 13

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

try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}

Ответ 14

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

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

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

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

Ответ 15

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

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

Ответ 19

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