Чому я повинен писати всі заяви в Try-Catch?


12

Керівник моєї компанії каже, що я повинен написати все, тобто ВСІЙ код у висловлюваннях Try-catch. Тепер я можу зрозуміти підхід "краще бути безпечним, ніж шкодувати", але хіба це не надто куряче серце, щоб думати, що буде виняток, коли створюються мітки, встановлюється позиція форми. чи були випадки, коли винятки в таких простих операціях.


4
Це звучить як терміни гудіння одних і тих же людей, які кажуть, що всі SQL повинні бути записані як збережені процедури для кращої продуктивності.
губка

5
Ви б хотіли: "Якщо ваш код створює помилку під час запуску, вас звільняють". Гра в курку - це задоволення, поки ви не побачите, як опонент кидає кермо і педаль гальма у вікно.
JeffO

4
@Jeff O - Я фактично вірю, що в розробці програмного забезпечення опонент - вантажний поїзд.
Joris Timmermans

5
Найкращий вираз, який я чув для цього стилю поводження з винятками, - це "прибивання трупа у вертикальному положенні", тобто він залишає додаток у несподіваному стані. Fail Fast, Fail Loudly - це набагато сучасніший підхід, тому ви можете реально працювати з усіма помилками.
Брук

2
Тема запиту не має значення ... просто кажучи, що "керівник моєї компанії каже, що я повинен кодувати ..." - це великий червоний прапор. Це мікроменеджмент ... це не його робота.
JoelFan

Відповіді:


14

Керівник моєї компанії каже, що я повинен написати все, тобто ВСІЙ код у висловлюваннях Try-catch.

Ну, це трохи переборщило і просто призводить до галасливого коду. Які переваги в тому, щоб весь код (кожен метод, наприклад) був написаний за допомогою обробника спробу вловлювання? Він просто говорить вам про помилку, яку потрібно виправити в більшості випадків. Часто винятків можна і слід уникати в першу чергу.

Огляд сліду стека здебільшого достатній, щоб виявити причину у вашому коді, навіть якщо несправний метод не виконує сам вилов. Бувають випадки, коли розробники пошкоджують сліди стека за винятками, але це набагато частіше трапляється, коли у вас багато і багато оброблювачів винятків. Як і все: Трохи добре, але занадто багато його - отрута.

Поводження з винятками дійсно досить просте:

Виключення з лову

  • щоразу, коли вам потрібна спеціальна дія як реакція на виняток
  • всякий раз, коли виняток залишає програму в непослідовному стані, якщо її не обробляють

Якщо ви задумаєтесь, то завжди завжди є лише одне місце, яке добре обробляти винятковим випадком. І таким чином обробник повинен знаходитися в тому місці.

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

Пам’ятайте, що рано впасти, коли все піде (непоправно) не так. Вносити весь код у висловлювання про помилки - це абсурд, але не забудьте повідомити та записати ВСІ винятки.


+1 Це не тільки призводить до галасливого коду, але ще гіршої продуктивності. Якщо ви помістите заяви в блок спробу, компілятор HotSpot не зможе застосувати оптимізації, які він інакше зробив би.
Олівер Вайлер

@Oliver Weiler: Чи є у вас цитування, що пояснюють, які оптимізації компілятор HotSpot не робить у блоках спробу / лову?
Кайпро II

16

але чи не надто куряче, щоб думати, що буде виняток, коли створено Мітки, буде встановлено положення форми. чи були випадки, коли винятки в таких простих операціях.

Абсолютно так! Завжди є спосіб, щоб все пішло не так, чого ви не передбачили. І «куряче серце» - це смішний вираз, який слід використовувати в цьому контексті; розробка програмного забезпечення полягає не в тому, щоб довести ваш махізм через ігнорування потенційних проблем.

Що це дійсно питання , чи є це корисно для виключення бути спійманим в точці , де ваші стандарти кодування кажуть , що вони повинні. Ваша заява звучить так, що вам потрібно мати блок "try / catch" навколо кожного методу, і це дійсно абсурдно, оскільки ви часто не можете одразу зробити щось корисне за винятком, і це фактично вся суть винятків: ви можете вибрати, щоб дозволити їм розповсюджують стек викликів, який повинен бути вирішений у відповідній точці.


13
Мої програми знають краще, ніж кидати винятки, інакше вони отримають побиття свого життя. Як тільки вони подумають, що ти курячий, вони зіткнуться з усіма тобою.
JeffO

@Michael Borgwardt: хе-хе, значить, ти мене зневажив. Ви заявили про це питання, і єдиний аккаунт є на моїй посаді. Здається, у вас є серйозна проблема зі своїм егою або самооцінкою. Я помітив, що і на інших квітах. Знаєте, і інші програмісти мають хороші відповіді.
Сокіл

@Falcon: Я нічого не спростовував з цього питання. Я поняття не маю, що змушує вас повірити в інше, але якщо хтось має серйозну проблему его, це ви.
Майкл Боргвардт

@Michael Borwardt: Можливо, я помиляюся. У такому випадку прошу вибачення. Це може бути, що саме голосування щодо вашого власного питання змусило мене думати, що ви тут прихильнилися. Вибачте.
Falcon

8

Я б обернув це навпаки. Так, як правило, обробка виключень - це хороша річ, але чи можете ви насправді обробляти кожен можливий виняток розумним чином у тому місці, де його спіймали? Іноді, особливо якщо ви не пишете програмне забезпечення, що має найважливіше значення для місії, краще просто вийти з ладу та спалити деяким наполовину контрольованим способом, коли справи йдуть жахливо не так.

Якщо ви не можете бути на 100% впевнені, що ви можете обробити кожен виняток, який, можливо, може бути спійманий, вам, ймовірно, краще написати якийсь загальний обробник винятків, загорнувши в нього головний цикл програми - точну механіку того, як це зробити очевидно залежить від того, на якій мові ви працюєте в Там, журнал так докладно про виключення , як ви можете, зберегти стан програми (де - то. інший , ніж будь-які дані , зберігати користувач в даний час працює проти - пам'ятайте, що все це може призвести до пошкодження в цій точці ), і так далі. Тоді повторно скиньте виняток і дозвольте ОС обробляти його, як не вважає за потрібне. У цьому оброблювачем винятків, що стосується всіх винятків, будьте готові до катастрофічних збоїв. Потім, коли програма перезапущена, подивіться, чи корисний цей стан, і відновіть те, що можна виправити, якщо воно є; і, можливо, запропонуйте користувачеві надіслати вам повідомлення про помилку.


5
+1: Ніколи не ловіть виняток, якщо ви не зможете негайно правильно впоратися з цим. (На жаль, іноді вам доводиться потрапляти в пастку просто для того, щоб він знову не міг вільно розігруватися, але позначений як інший тип, як частина примусового API: Я ненавиджу це.)
Дональд стипендіатів

6

Загалом, використання спробувати / ловити стільки застаріло, оскільки блок лову так дорогий з точки зору ресурсів. Спробуйте / зловити використання нагадує мені управління ризиками . Управління ризиками має два виміри:

  1. Ймовірність виникнення ризику
  2. Шкода, яку він може мати

Тепер, якщо ви виходите з дому, фортепіано кудись падає на вашу голову, поки така ймовірність не трапиться (можливо 0,001%), але може вбити вас.

Обробка винятків така. Спробуйте блок не дорого. Але блок лову дійсно дорогий, тому що йому потрібно створити таблицю сліду стека та виконувати інші речі. Тому, приймаючи рішення про спробувати / ловити блоки, слід враховувати, скільки разів ви, мабуть, потрапили на блок лову. Якщо серед 10 000 звичаїв ви потрапили в нього лише 1 раз, тоді використовуйте його. Але якщо це форма, і користувач, ймовірно, не заповнює її правильно 50% разів, тоді вам слід уникати введення блоку спробу / лову.

У місцях, де ймовірність виникнення винятків висока, рекомендується використовувати if {} else {}блоки, щоб уникнути виникнення виключень. Наприклад, де ви хочете розділити два числа, а не писати:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

ви повинні написати:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}

2
+1 для використання if / else для боротьби зі "винятками", які в основному є лише логікою програми.
Морган Херлокер

Якщо це стосується користувачів, пам’ятайте, що комп'ютери значно швидше, ніж люди. Виняток, закинутий у 50% поданих форм, все ще може траплятися лише кілька разів на секунду навіть у багатьох користувачів.
Дональні стипендіати

1
Я не згоден з вами щодо уникнення блоків спробу / лову. Постійно намагаючись передбачити винятки, це схильність до помилок, дорога в часі розробника, і робить ваш код важче читати. Цикл, який викидає мільйон винятків і виловлює їх, займає на моїй машині 500 мс (проти 1 мс для порожнього циклу), що не є різницею продуктивності в реальному світі в 99,99% випадків (і всього коду інтерфейсу). Ви повинні використовувати винятки, за винятком випадків, коли ви знаєте, що покарання за ефективність має значення, оскільки воно робить ваш код більш надійним і дозволяє припускати, що попередній код виконано успішно.
Кайпро II

@ cosmic.osmo, ви отримуєте стек-трек чи просто його ловите?

3

Ви повинні використовувати пробний лов, коли це доречно, але, будь ласка, о, будь ласка, не ловіть всі винятки і навіть не записуйте їх. У цей момент це кодовий запах і нерозумна робота.


1
+1 для ведення журналу. Програми в дикій природі - це чорні скриньки. Коли вони не вдається, журнал із написом "Ось, що сталося" проходить дуже довгий шлях до вирішення проблеми. У моїх програмах були помилки, які не повідомили, і їх було розкрито лише після того, як я знайшов їх у журналі.
Ендрю Нілі

2

Я особисто не витримую винятків, вони ДУЖЕ, ДУЖЕ, ДУЖЕ важко правильно поводитися. І намагатися зіпсувати пошкоджені дані - ДУЖЕ, ДУЖЕ, ДУЖЕ важко!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

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

Якщо ви не викликаєте будь-яку функцію, наприклад:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

Ви не зможете правильно прибиратись у кожній точці виходу. Винятки становлять HARD!

Єдине добре у винятках - це те, що якщо ви їх не зловите, додаток виходить з ладу при несподіваній поведінці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.