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

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

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

try
{
    //Some code
}
catch(Exception){}

Ответы [ 19 ]

44 голосов
/ 26 июля 2010

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

24 голосов
/ 26 июля 2010

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

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

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

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

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

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

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

15 голосов
/ 26 июля 2010

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

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

9 голосов
/ 26 июля 2010

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

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

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

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

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

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

Приложение через четыре года после моего первоначального поста

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

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

7 голосов
/ 26 июля 2010

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

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

6 голосов
/ 27 июля 2010

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

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

5 голосов
/ 26 июля 2010

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

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

5 голосов
/ 22 октября 2010

Я считаю, что это из-за проверенных исключений Java.Я лично ненавижу их из-за этого, потому что люди склонны думать, что им везде нужен код обработки исключений.IMO в 99% кода, вы должны просто выбросить свое исключение в стек и не обрабатывать его.Я был бы счастлив, если бы в сигнатуре по умолчанию для любого нового созданного метода было «бросает исключение», чтобы мне не приходилось иметь дело с исключениями, если я не хочу.в двух местах: 1. Для очистки ресурсов, таких как закрытие входного потока, подключение к базе данных или удаление файла.2. В самом верху стека, где вы перехватываете исключение и либо регистрируете его, либо показываете его пользователю.

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

1 голос
/ 26 июля 2010

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

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

1 голос
/ 10 января 2012

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

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

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

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