Я только что видел вопрос о try-catch , какие люди (включая Jon Skeet) говорят, что пустые блоки catch - это действительно плохая идея? Почему это? Нет ли ситуации, когда пустой улов не является неправильным дизайнерским решением?
Я имею в виду, например, что иногда вы хотите получить некоторую дополнительную информацию откуда-то (веб-сервис, база данных), и вам действительно все равно, получите вы эту информацию или нет. Таким образом, вы пытаетесь получить его, и если что-то случится, это нормально, я просто добавлю "catch (Exception игнорируется) {}", и это все
exception-handling
try-catch
Самуэль Каррихо
источник
источник
Ответы:
Обычно пустой try-catch - плохая идея, потому что вы молча проглатываете состояние ошибки и затем продолжаете выполнение. Иногда это может быть правильным, но часто это признак того, что разработчик увидел исключение, не знал, что с этим делать, и поэтому использовал пустую заглушку, чтобы заставить проблему замолчать.
Это программный эквивалент наложения черной ленты на сигнальную лампу двигателя.
Я считаю, что то, как вы справляетесь с исключениями, зависит от того, на каком уровне программного обеспечения вы работаете: Исключения в тропическом лесу .
источник
Они плохая идея в целом , потому что это действительно редкое заболевание , при котором отказ (исключительное условие, в более общем плане ) правильно встретились с ответом NO вообще. Кроме того, пустые
catch
блоки являются распространенным инструментом, используемым людьми, которые используют механизм исключений для проверки ошибок, что они должны делать упреждающе.Сказать, что это всегда плохо, неправда ... это правда очень мало. Могут быть обстоятельства, когда либо вас не волнует, что произошла ошибка, либо наличие ошибки как-то указывает на то, что вы все равно ничего не можете с этим поделать (например, при записи предыдущей ошибки в текстовый файл журнала и вы получаете
IOException
, то есть вы все равно не можете выписать новую ошибку).источник
Я бы не стал растягиваться, если бы сказал, что тот, кто использует пустые блоки catch, плохой программист и не знает, что делает ...
Я использую пустые блоки catch при необходимости. Иногда программист библиотеки, которого я потребляю, не знает, что делает, и выдает исключения даже в ситуациях, когда это никому не нужно.
Например, рассмотрим некоторую библиотеку http-сервера, мне было бы наплевать, если сервер выдает исключение, потому что клиент отключился и
index.html
не может быть отправлен.источник
Есть редкие случаи, когда это может быть оправдано. В Python вы часто видите такую конструкцию:
Так что может быть нормально (в зависимости от вашего приложения) сделать:
В недавнем проекте .NET мне пришлось написать код для перечисления подключаемых библиотек DLL, чтобы найти классы, которые реализуют определенный интерфейс. Соответствующий фрагмент кода (в VB.NET, извините):
Хотя даже в этом случае я бы признал, что регистрация ошибки где-то, вероятно, была бы улучшением.
источник
Пустые блоки захвата обычно вставляются, потому что кодер действительно не знает, что они делают. В моей организации пустой блок catch должен содержать комментарий о том, почему не делать ничего, кроме исключения, - хорошая идея.
Что касается примечания, большинство людей не знают, что за блоком try {} может следовать либо catch {}, либо finally {}, требуется только один.
источник
Исключения следует выбрасывать только в том случае, если есть действительно исключение - что-то происходящее за пределами нормы. Пустой блок catch в основном говорит «что-то плохое происходит, но мне просто все равно». Это плохая идея.
Если вы не хотите обрабатывать исключение, пусть оно распространяется вверх, пока не достигнет некоторого кода, который может его обработать. Если ничто не может обработать исключение, оно должно закрыть приложение.
источник
catch (Exception) {}
это плохая идея,catch (SpecificExceptionType) {}
может быть, все в порядке. Программист DID проверяет исключение, используя информацию о типе в предложении catch.Я думаю, что это нормально, если вы поймаете определенный тип исключения, который, как вы знаете, будет вызван только по одной конкретной причине, и вы ожидаете это исключение и действительно не должны ничего с этим делать.
Но даже в этом случае отладочное сообщение может быть в порядке.
источник
Пер Джош Блох - Статья 65: Не игнорируйте исключения из эффективной Java :
источник
Пустой блок catch по сути говорит: «Я не хочу знать, какие ошибки выдаются, я просто буду их игнорировать».
Это похоже на VB6
On Error Resume Next
, за исключением того, что все, что находится в блоке try после исключения, будет пропущено.Что не помогает, когда что-то ломается.
источник
Это идет рука об руку с «Не используйте исключения для управления потоком программ» и «Используйте исключения только для исключительных обстоятельств». Если это сделано, то исключения должны возникать только тогда, когда есть проблема. И если есть проблема, вы не хотите молча провалиться. В редких аномалиях, когда нет необходимости решать проблему, вы должны, по крайней мере, регистрировать исключение, на тот случай, если аномалия больше не станет аномалией. Единственное, что хуже, чем потерпеть неудачу - это молча провалиться.
источник
Я думаю, что полностью пустой блок catch - плохая идея, потому что нет никакого способа сделать вывод, что игнорирование исключения было предполагаемым поведением кода. В некоторых случаях не обязательно плохо проглатывать исключение и возвращать false или null или какое-либо другое значение. .NET Framework имеет много методов "try", которые ведут себя таким образом. Как правило, если вы проглотили исключение, добавьте комментарий и оператор журнала, если приложение поддерживает ведение журнала.
источник
Потому что , если исключение будет брошено вы никогда не будете видеть это - провал молча худшие из возможных вариантов - вы получите ошибочное поведение и не идеи , чтобы посмотреть , где это происходит. По крайней мере, поместите туда лог-сообщение! Даже если это то, что «никогда не случится»!
источник
Пустые блоки catch указывают на то, что программист не знает, что делать с исключением. Они подавляют исключение от возможного появления пузырей и правильной обработки другим блоком try. Всегда старайтесь делать что-то, за исключением того, что вы ловите.
источник
Я считаю, что больше всего раздражает пустые операторы catch, когда это делает какой-то другой программист. Я имею в виду, что когда вам нужно отладить код у кого-то еще, любые пустые операторы catch делают такое начинание более трудным, чем это должно быть. IMHO операторы catch всегда должны показывать какое-то сообщение об ошибке - даже если ошибка не обрабатывается, она должна по крайней мере ее обнаружить (альтернативно, только в режиме отладки)
источник
Это, вероятно, никогда не правильно, потому что вы молча пропускаете все возможные исключения. Если есть конкретное исключение, которое вы ожидаете, то вы должны проверить его, пересмотреть, если это не ваше исключение.
источник
Как правило, вы должны ловить только те исключения, которые вы можете обработать. Это означает быть как можно более конкретным при отлове исключений. Поймать все исключения редко бывает хорошей идеей, а игнорировать все исключения - почти всегда очень плохой идеей.
Я могу вспомнить лишь несколько случаев, когда пустой блок catch имеет какое-то значимое назначение. Если какое-то конкретное исключение, которое вы перехватываете, «обрабатывается», просто повторяя попытку действия, в блоке перехвата не нужно будет ничего делать. Однако было бы неплохо зарегистрировать факт возникновения исключения.
Другой пример: CLR 2.0 изменил способ обработки необработанных исключений в потоке финализатора. До версии 2.0 процессу было позволено пережить этот сценарий. В текущем CLR процесс завершается в случае необработанного исключения в потоке финализатора.
Имейте в виду, что вы должны реализовывать финализатор только в том случае, если он вам действительно нужен, и даже в этом случае вы должны делать как можно меньше в финализаторе. Но если любая работа, которую должен выполнить ваш финализатор, может вызвать исключение, вам нужно выбирать между меньшим из двух зол. Вы хотите закрыть приложение из-за необработанного исключения? Или вы хотите перейти в более или менее неопределенное состояние? По крайней мере, в теории последнее может быть меньшим из двух зол в некоторых случаях. В этом случае пустой блок catch не позволит завершить процесс.
источник
Так что, следуя вашему примеру, в этом случае это плохая идея, потому что вы ловите и игнорируете все исключения. Если бы вы ловили только
EInfoFromIrrelevantSourceNotAvailable
и игнорировали это, это было бы хорошо, но это не так. Вы также игнорируетеENetworkIsDown
, что может или не может быть важным. Вы игнорируетеENetworkCardHasMelted
иEFPUHasDecidedThatOnePlusOneIsSeventeen
, что почти наверняка важно.Пустой блок catch не является проблемой, если он настроен на перехват (и игнорирование) исключений определенных типов, которые, как вы знаете, не важны. Ситуации, в которых целесообразно подавлять и беззвучно игнорировать все исключения, не останавливаясь для их предварительного изучения, чтобы выяснить, ожидаемые они / нормальные / неактуальные или нет, чрезвычайно редки.
источник
Есть ситуации, когда вы можете их использовать, но они должны быть очень редкими. Ситуации, где я мог бы использовать один из них:
регистрация исключений; в зависимости от контекста вы можете захотеть разместить необработанное исключение или сообщение.
зацикливание технических ситуаций, таких как рендеринг или обработка звука, или обратный вызов списка, когда само поведение будет демонстрировать проблему, выбрасывание исключения будет только мешать, а регистрация исключения, вероятно, просто приведет к тысячам сообщений «fail to XXX» ,
программы, которые не могут потерпеть неудачу, хотя они должны хотя бы что-то регистрировать.
я обнаружил, что для большинства приложений winforms достаточно иметь один оператор try для каждого пользовательского ввода. Я использую следующие методы: (AlertBox - просто быстрая оболочка MessageBox.Show)
Тогда каждый обработчик события может сделать что-то вроде:
или
Теоретически, вы можете использовать TryActionSilently, который может быть лучше для рендеринга вызовов, чтобы исключение не создавало бесконечное количество сообщений.
источник
Если вы не знаете, что делать в блоке catch, вы можете просто зарегистрировать это исключение, но не оставляйте его пустым.
источник
Вы никогда не должны иметь пустой блок catch. Это похоже на сокрытие ошибки, о которой вы знаете. По крайней мере, вы должны записать исключение в файл журнала для последующего просмотра, если вам не хватает времени.
источник