Почему плохая обработка исключений?

93

Язык Google Go не имеет исключений как выбор дизайна, и Линус, известный в Linux, назвал исключения чушью. Почему?

Joemoe
источник
2
Создатель ZeroMQ пишет о том, что, по его мнению, было ошибкой писать его на C ++ (в основном из-за обработки ошибок) 250bpm.com/blog:4
serbaut
Go может не иметь исключений, но у него есть «паники», от которых вы можете «избавиться» (пока все еще выполняются отложенные операторы) и которые обеспечивают нелокальный поток управления ...
Керрек С.Б.
Вот хорошая статья lighterra.com/papers/exceptionsharmful (Обработка исключений считается вредной)
masterxilo
Afaics, исключения могут быть смоделированы в Go с помощью значительного шаблона , хотя этот момент может быть более значимым для транспиляции из синтаксического сахара, чем для написания шаблона вручную.
Shelby Moore III

Ответы:

83

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

Рассмотрим на простом примере что-то вроде этого:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

Если предположить , что FrobManagerволя deleteк FrobObject, это выглядит нормально, не так ли? Или, может быть, нет ... Представьте, что либо либо, FrobManager::HandleFrob()либо operator newвыдаст исключение. В этом примере приращение m_NumberOfFrobsне откатывается. Таким образом, любой, кто использует этот экземпляр, Frobberможет иметь поврежденный объект.

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

Например, вы можете думать об этом, как о мьютексах. Внутри критического раздела вы полагаетесь на несколько операторов, чтобы убедиться, что структуры данных не повреждены и другие потоки не могут видеть ваши промежуточные значения. Если какое-либо из этих утверждений случайно не выполняется, вы попадаете в мир боли. Теперь уберите блокировки и параллелизм и подумайте о каждом подобном методе. Думайте о каждом методе как о транзакции перестановок состояния объекта, если хотите. В начале вызова метода объект должен быть в чистом состоянии, а в конце также должно быть чистое состояние. Между ними переменная fooможет не соответствоватьbar, но ваш код со временем исправит это. Что означают исключения, так это то, что любое из ваших утверждений может прервать вас в любой момент. В каждом отдельном методе ответственность лежит на вас, чтобы исправить это и откатиться, когда это произойдет, или упорядочить свои операции, чтобы выбросы не влияли на состояние объекта. Если вы ошиблись (а сделать такую ​​ошибку легко), то вызывающий абонент увидит ваши промежуточные значения.

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

О безопасном кодировании на C ++ написаны целые книги. Многие эксперты ошиблись. Если это действительно так сложно и имеет так много нюансов, возможно, это хороший знак, что вам нужно игнорировать эту функцию. :-)

Асвейкау
источник
9
Интересный ответ, но он ничего не отражает в моем опыте программирования. Поэтому я предполагаю, что это либо зависит от культуры (может быть, больше проблема в Java или C ++, чем, скажем, в Python), либо в конкретной предметной области.
ddaa
42
Исключения, написанные на управляемом языке с использованием шаблона try-catch-finally, никогда не должны оставлять недопустимое состояние, если они написаны правильно; так как блок finally гарантированно будет выполнен, объекты могут быть освобождены оттуда. Об остальном должны позаботиться переменные, выходящие за пределы области видимости и сборка мусора.
Роберт Харви
7
@ddaa Проблема определенно возможна в Python. В результате обычно бывает трудно воспроизвести ошибку. Возможно, вы были особенно дотошны или удачливы. Но тогда вы правы, что это больше проблема C ++, где наиболее распространенной ошибкой из-за плохого EH является утечка памяти. Я постарался подчеркнуть, что утечки - не самая серьезная проблема. @Robert GC уменьшит утечку памяти, но я не уверен, что управляемый код избавит вас от ошибки программиста. В частности, если кто-то не обращает внимания на безопасность исключений, потому что не думает, что это проблема на его языке, это плохой знак.
asveikau
4
@lzprgmr, безусловно, есть: исключения позволяют вам иметь дело с diff. типы ошибок при разн. места в коде. Обработка ошибки подключения может потребовать повторного подключения, но не в середине глубоко вложенной функции. Вы хотите передать это диспетчеру соединений или чему-то еще. Затем работа с возвращаемыми значениями заставляет вас проверять ошибки при каждом отдельном вызове и всплывать их вручную (например, в случае ошибки сброса соединения). Кроме того, возвращаемые значения складываются во вложенных вызовах: func3 может возвращать -1, func2 вызывает func3, возвращает -2 при своих ошибках, -1 для func3 и т. Д.
abourget
4
Я голосовал против, но я отменил это, потому что это причина, по которой на исключения смотрят свысока. Однако, на мой взгляд, почти любой метод или фрагмент кода могут дать сбой. Вы не можете обработать каждое условие ошибки, вводя для него возвращаемое значение. Вы потеряете информацию об ошибке. Мысль о том, что вы можете сохранить все хорошо синхронизированным, проверяя каждый оператор и выполняя очистку, приводит к очень запутанному коду - обнаружение ошибки в нескольких операторах и очистка одного или двух ресурсов, не связанных с GC, намного чище.
Maarten Bodewes
50

Причина отсутствия исключений в Go объясняется в FAQ по языковому дизайну Go:

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

Как и дженерики, исключения остаются открытой проблемой.

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

ОБНОВЛЕНИЕ - май 2012 г.

Теперь дизайнеры Go слезли с забора. В их FAQ теперь говорится следующее:

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

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

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

Подробнее см. В статье «Отложить, паника и восстановление».

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


... и Линус, известный в Linux, назвал исключения чушью.

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

«Вся обработка исключений в C ++ фундаментально нарушена. Особенно это касается ядер».

Вы заметите, что он говорит об исключениях C ++ в частности, а не об исключениях в целом. (И исключения C ++ , по- видимому, имеют некоторые проблемы, из-за которых их сложно использовать правильно.)

Я пришел к выводу, что Линус вообще не называл исключения (в общем) «чушью»!

Стивен С
источник
30
Ненавижу, когда информацию скрывают, помещая ее в FAQ. :)
brian d foy
7
Обратите внимание, что Линус начинает это электронное письмо со слов «C ++ - ужасный язык». и продолжает разглагольствовать о том, как сильно он ненавидит C ++ и людей, которые предпочитают программировать на нем. Следовательно, я не думаю, что его мнение об исключениях C ++ можно считать достоверным, учитывая его несколько предвзятое мнение о C ++.
Pharap
1
@ Hi-Angel - Как сказано в приведенном мной тексте: «Для простой обработки ошибок многозначные возвращаемые значения Go позволяют легко сообщить об ошибке, не перегружая возвращаемое значение». . Вот как это связано. В любом случае, я цитирую доводы дизайнеров Go. Если хочешь спорить, спорь с >> ними <<.
Stephen C
1
@ Hi-Angel, я не писал эти абзацы. Я их просто процитировал. Если у вас есть проблемы с ними, вы, вероятно, должны обсудить это с авторами. Теоретически я мог бы предоставить учебник по языку Go в качестве контекста. Но, честно говоря, люди, которые не понимают терминологию Go, могут посетить веб-сайт Go, чтобы узнать, что все это значит.
Stephen C
1
".. приводит к запутанному коду" Давным-давно я написал программу на C со многими строковыми операциями. Каждый метод выделял память, а затем проверял, было ли выделение успешным. Оказалось, что большая часть кода просто проверяла распределения. Разве это не запутанно? C ++ с исключениями стал для меня большим спасением.
робсосно
30

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

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

Роберт Харви
источник
9
@Robert: «вы не должны использовать их для управления потоком программы», я не думал об этом таким образом, новая перспектива для меня: P +1
okw
2
Это тоже действительно зависит от языка. Трудно избежать исключений, например, если вы программируете на Java.
Чарльз Сальвия
2
@Charles: Я думаю, дело в том, что исключения подходят в ситуациях, которые указывают на ошибку, неправильно настроенную систему или необоснованные вводы. Большинство исключений библиотеки Java можно избежать с помощью кода «нормального рабочего процесса».
Artelius
6
они не должны стоить дорого. например, вы можете реализовать «попытку», которая требует нулевого времени выполнения, и «выбросить» обработчики исключений в таблице на основе адресов вызывающих абонентов, которые он видит в стеке ... Я бы сказал, что самые большие причины не делать этого. исключения использования совершенно не связаны с производительностью.
asveikau
Перефразировано; вопрос явно намекает на использование исключений в целом или не использование исключений вообще (они дерьмо или даже не на языке). Ваш ответ только показывает, почему исключения плохо сказываются на производительности при использовании для потока управления программой.
Maarten Bodewes
27

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

Независимо от того, какой язык вы используете, возьмите копию Руководства по дизайну Framework : соглашения, идиомы и шаблоны для многоразовых библиотек .NET (2-е издание). Глава о генерировании исключений не имеет аналогов. Несколько цитат из первого издания (у меня 2-е):

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

Есть страницы с заметками о преимуществах исключений (согласованность API, выбор местоположения кода обработки ошибок, повышенная надежность и т. Д.). Есть раздел о производительности, который включает в себя несколько шаблонов (Tester-Doer, Try-Parse).

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

TrueWill
источник
4
Я не могу согласиться с этим. Я не против исключений, и эта книга просто необходима, однако она ориентирована на разработку .NET и C #.
3
Я знаю, что это давно, просто хотел прокомментировать, что, похоже, между типом .NET и типом * nix будет общее разногласие. Все библиотеки, которые я использовал в качестве разработчика Linux, используют коды возврата, а руководства по стилю * nix, которые я читал (например, моя компания и Google ), просто говорят: «Мы не делаем исключений». Думаю, это интересно.
jarvisteve
1
Платформы должны обрабатывать исключения иначе, чем приложения конечного пользователя. У фреймворков нет другого способа справляться с ошибками, кроме создания исключения, в отличие от потребительских приложений.
0x6C38
12

С точки зрения golang, я полагаю, что отсутствие обработки исключений делает процесс компиляции простым и безопасным.

С точки зрения Линуса, я понимаю, что код ядра ВСЕ касается угловых случаев. Так что есть смысл отказаться от исключений.

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

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

ddaa
источник
Но то, что верно для кода ядра, верно и для длительно выполняющихся собственных серверных процессов.
Лотар
11

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

  1. Не используйте исключения для управления потоком программы, т. Е. Не полагайтесь на операторы catch для изменения потока логики. Это не только скрывает различные детали логики, но и может привести к снижению производительности.
  2. Не генерируйте исключения из функции, если возвращаемый «статус» имеет больше смысла - генерируйте исключения только в исключительной ситуации. Создание исключений - дорогостоящая и требовательная к производительности операция. Например, если вы вызываете метод открытия файла, но этот файл не существует, вызовите исключение FileNotFound. Если вы вызываете метод, который определяет, существует ли учетная запись клиента, возвращайте логическое значение, не возвращайте исключение «CustomerNotFound».
  3. При определении того, обрабатывать ли исключение или нет, не используйте предложение «try ... catch», если вы не можете сделать что-то полезное с исключением. Если вы не можете обработать исключение, просто позвольте ему подняться в стеке вызовов. В противном случае исключения могут быть «проглочены» обработчиком, и детали будут потеряны (если вы не повторно выбросите исключение).
Джефф Брамвелл
источник
2
Вернуть статус - дело непростое. Я видел слишком много кода, в котором метод GetCustomer возвращает объект Customer в случае успеха или null в случае неудачи. Во многих случаях вызывающий код никогда не проверял результат, а сразу обращался к Заказчику. Это срабатывало в большинстве случаев ...
TrueWill
3
Но если GetCustomer выдает исключение вместо возврата null, клиентский код все равно должен обрабатывать исключение. Независимо от того, проверяет ли это значение на null или обрабатывает исключения, ответственность лежит на клиентском коде - если он что-то не выполняет должным образом, то рано или поздно что-то взорвется.
Крис
1
@TrueWill Языки, поддерживающие шаблоны / универсальные шаблоны, решают эту проблему, возвращая Option<T>вместо nullnow. Например, только что познакомился с Java 8, взяв подсказку от Guava (и других).
Maarten Bodewes
@owlstead Ага. Любите монаду «может быть». Это хороший способ, если ваш язык поддерживает его и предлагает сопоставление с образцом.
TrueWill
@owlstead Опять же, то, что сказал Крис, по-прежнему актуально для этого - пользователь должен помнить о вызове функции .orElse (defaultObject) или какой бы идиомой ни был выбран рассматриваемый язык. В конце концов, проблема скорее в программистах, чем в методе обработки ошибок.
Pharap
9

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

http://www.joelonsoftware.com/items/2003/10/13.html

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

Тим Сильвестр
источник
1
В коде C есть исключения, только по-другому. Вам нужно заключить каждый вызов нетривиальной функции в ifs, что делает использование этого языка головной болью!
RCIX
1
Также есть setjmp/ longjmpstuff, что довольно плохо.
Тим Сильвестр
9
Вы действительно хотите прислушаться к совету человека, который ценит программистов Duct Tape и не верит в необходимость модульных тестов? joelonsoftware.com/items/2009/09/23.html
TrueWill,
4
Это классическая ошибка (или обман) в дискуссии, когда аргументы по теме заменяются отсылками к личности. Обычно это признак ухудшения дискуссии.
Петр Гладких
1
@PetrGladkikh Обсуждение началось с OP, ссылаясь на мнение Линуса ... этот чит известен как заблуждение обращения к власти. Дискуссия может только пойти в гору, и ответ на вопрос о том, почему Линус не любит исключений, ссылаясь на свою личность, - это не обман.
Джим Балтер,
7

Исключения неплохие. Они хорошо вписываются в модель RAII C ++, которая является самой элегантной особенностью C ++. Если у вас уже есть код, небезопасный в отношении исключений, то он плох в этом контексте. Если вы пишете действительно низкоуровневое программное обеспечение, такое как ОС Linux, тогда оно плохое. Если вам нравится засорять свой код кучей проверок возврата ошибок, то они бесполезны. Если у вас нет плана управления ресурсами при возникновении исключения (которые предоставляют деструкторы C ++), то они плохие.

Павел
источник
7
RAII полезен даже без исключений.
Марк Рэнсом
4
однако исключения бесполезны без RAII (или другого автоматического управления ресурсами).
Грег Роджерс
+1 за указание на ситуации, когда исключения неуместны и что исключения не являются плохими по своей сути.
Pharap
4

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

Допустим, вы работаете над проектом, и каждый контроллер (около 20 различных основных) расширяет один контроллер суперкласса с помощью метода действия. Затем каждый контроллер выполняет кучу вещей, отличных друг от друга, вызывая объекты B, C, D в одном случае и F, G, D в другом случае. Здесь на помощь приходят исключения во многих случаях, когда код возврата был огромным и КАЖДЫЙ контроллер обрабатывал его по-разному. Я взломал весь этот код, выдал правильное исключение из «D», поймал его в методе действий контроллера суперкласса, и теперь все наши контроллеры согласованы. Раньше D возвращал ноль для НЕСКОЛЬКИХ различных случаев ошибок, о которых мы хотели сообщить конечному пользователю, но не могли, а я этого не сделал.

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

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

Дин Хиллер
источник
1
+1 Однозначно один из лучших аргументов в пользу использования исключений, которые я читал. Можно было бы использовать более подробные примеры (например, диаграмму UML, какой-то псевдокод или какой-то реальный код), но идея обеспечения согласованной работы подклассов - хорошая. Кроме того, тот факт, что ваше свидетельство является анекдотическим, показывает, что исключения полезны в реальных ситуациях, а полезность - это основная цель любой языковой функции.
Pharap
в качестве дополнения, если вы используете scala, вы можете вместо этого вернуть Try [ResponseType], который представляет исключение или фактический ответ. Затем вы можете следовать тому же шаблону, который я избегал выше, без реальных исключений, кроме тех, которые используются в попытке. Тогда это похоже на то, что каждый ваш метод возвращает 1 + n типов ответов, которые, как мне кажется, необходимы. Однако в scala мы возвращаем Future [response], который работает так же, как Try, но может помочь с более асинхронным программированием.
Дин Хиллер
2

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

Но реальность - это совсем другое дело. У нас всегда бывают «неожиданные» ситуации. Вот почему нам нужны исключения.

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

Я думаю, что в Go они представят кое-что, что поможет справиться с «неожиданными» ситуациями. Я могу предположить, что они попытаются сделать так, чтобы это выглядело менее деструктивно как исключения и больше как логика приложения. Но это только мое предположение.

Майк Чалий
источник
2
«Посмотрите на функциональные языки, у них нет побочных эффектов, поэтому у них практически нет источника для обычных ситуаций». Это сильное преувеличение.
Stephen C
3
Что 5/0 по математике? Арчин (200)? Sqrt (-1)? В математике есть множество исключительных ситуаций.
Роберт Фрейзер,
3
Это не исключительные ситуации ... они просто не имеют значения ... и из-за этого могут быть реализованы как исключения ... но также могут быть реализованы как варианты предварительных условий ... так что это зависит от технической реализации.
Майк Чалий,
3
@MikeChaliy - Мне очень жаль, но это просто софизм. Вы можете применить такое рассуждение, чтобы сказать, что НИКАКОГО исключительных ситуаций не существует НИКОГДА. В действительности математические выражения, не имеющие значения (или не имеющие определенного значения), ЯВЛЯЮТСЯ исключительными. Это не означает, что с ними нужно бороться, выбрасывая и перехватывая исключения ... но если вы этого не сделаете, вам понадобятся либо специальные значения (например, Inf и Nan), либо операции, возвращающие несколько значений. Короче говоря, эти случаи требуют особого отношения.
Stephen C
1
Компьютеры - это машины состояний. Не идеальный математический мир.
Арунав Саньял
1

Парадигма обработки исключений C ++, которая составляет частичную основу для Java и, в свою очередь, .net, вводит некоторые полезные концепции, но также имеет некоторые серьезные ограничения. Одно из ключевых намерений разработки обработки исключений - позволить методам гарантировать, что они будут либо удовлетворять своим пост-условиям, либо генерировать исключение, а также гарантировать, что любая очистка, которая должна произойти до выхода метода, произойдет. К сожалению, все парадигмы обработки исключений в C ++, Java и .net не обеспечивают никаких хороших средств обработки ситуации, когда неожиданные факторы препятствуют выполнению ожидаемой очистки. Это, в свою очередь, означает, что нужно либо рискнуть, что все резко остановится, если произойдет что-то неожиданное (подход C ++ к обработке исключения происходит во время раскрутки стека),

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

суперкар
источник
1

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

kingfrito_5005
источник
По крайней мере, в Java у вас будет трассировка стека для каждого исключения, которая будет отображать всю цепочку вызовов с ToString () в ней.
ddekany
0
  • Необработанное исключение - это вообще плохо.
  • Плохо обработанное исключение - это плохо (конечно).
  • «Хорошие / плохие качества» обработки исключений зависят от контекста / области видимости и уместности, а не ради этого.
хорошо
источник
0

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

Для сообщений об ошибках я обычно предпочитаю сигналы об ошибках. Все зависит от API, варианта использования и серьезности, а также от того, достаточно ли ведения журнала. Также я пытаюсь переопределить поведение иthrow Phonebooks() вместо этого. Идея состоит в том, что «Исключения» часто заходят в тупик, но «Телефонная книга» содержит полезную информацию о восстановлении после ошибок или альтернативных маршрутах выполнения. (Пока не нашел подходящего варианта использования, но продолжайте попытки.)

Марио
источник
0

Для меня вопрос очень простой. Многие программисты неправильно используют обработчик исключений. Больше языковых ресурсов - лучше. Уметь обрабатывать исключения - это хорошо. Одним из примеров неправильного использования является значение, которое должно быть целым числом, которое не проверяется, или другой ввод, который может делиться и не проверяться на деление нуля ... обработка исключений может быть простым способом избежать дополнительной работы и тяжелого мышления, программист может захотеть сделать грязный ярлык и применить обработку исключений ... Утверждение: «профессиональный код НИКОГДА не дает сбоев» может быть иллюзорным, если некоторые из проблем, обрабатываемых алгоритмом, являются неопределенными по своей природе. Возможно, в неизвестных по своей природе ситуациях в игру вступит обработчик исключений. Хорошие методы программирования являются предметом дискуссий.

Юрий
источник
Проблема не в том (или не должна быть) в том, может ли код выйти из строя - более серьезная проблема заключается в том, в какой степени, если код действительно не работает, нужно заботиться о деталях. Если кто-то пытается загрузить документ и один из методов «чтения данных» терпит неудачу, часто неважно, какой из них, поскольку результат один и тот же: документ не может быть загружен. По идее, для этого должна быть полезна обработка исключений. Проблема в том, что парадигмы обработки исключений в .NET и Java не предоставляют никакого удобного способа отличить «скучные» исключения, которые следует объединять вместе, от тех, которые не должны.
суперкар