Чи придушення помилок є поганою практикою?


14

На запитання ТА, який я запитав тут про якийсь код, про який я не був упевнений, хтось відповів "BTW, жахливий код там: він дуже часто використовує символ придушення помилки (@)".

Чи є причина, чому це погана практика? З такими речами, як:

$db=@new mysqli($db_info) or die('Database error');

, це дозволяє мені відображати лише власне повідомлення про помилку. Без придушення помилок, воно все одно відображатиме типове повідомлення PHP:

Попередження : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo не вдалося: Такого хоста не відомо. у деяких \ file \ шлях у рядку 6

а також "Помилка бази даних".

Чи придушення помилок завжди погано, і якщо так, то конкретно про вищезазначене погано?

Оновлення: фактичний код, який я використовую:

or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))

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


9
Ви носите зав'язані очі, коли ви керуєтесь поганою практикою?
Дейміен Рош

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

1
@SomeFreeMason Якщо мені потрібно налагодити помилку, я б просто встановив $ debug_mode на TRUE, оскільки фактичний код, який я використовую, є:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@Paradoxical: Я розумію, що стан виключення / обробки помилок у PHP трохи FUBAR, але ви знаєте, що ви можете вимкнути візуальне відображення помилок у вашій конфігурації PHP, правда?
Фоші

@Phoshi, на жаль, хостинг-сервіс, який я використовую, не дає мені доступу до php.ini

Відповіді:


14

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

Можливо, буде простіше вважати еквівалент, скажімо, на Java. Придушення помилки за допомогою @аналогічно проковтненню винятку. Наступний код, подібний до вашого, є розумним:

try {
    db = new MySQLi(dbInfo);
} catch (SQLException connectionFailure) {
    die("Database error");
}

(Ну, на Java, ви б не хотіли, щоб двигун сервлетів помер, але ви отримаєте ідею.)

Однак це не прийнятно:

try {
    db = new MySQLi(dbInfo);
} catch (Exception e) {
}

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


3
Я б не закликав наздоганяти виняток, а просто зупиняв виконання, щоб це "обробляти". Якщо ви зможете вирішити проблему, чудово, зробіть це. Якщо ти не можеш, що, чорт забираєш, це робиш? Це те, для чого ми маємо оброблювачів винятків вищого рівня. У цьому випадку винятки виловлюють лише переконання, що у вас є код обробки помилок, розповсюджений по всій кодовій базі даних.
Фоші

7

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

У цьому конкретному прикладі " Помилка бази даних " не є дуже хорошим повідомленням про помилку. Щось пішло не так із БД. Не дуже просвітницька. « Попередження: MySQLi :: MySQLi (): php_network_getaddresses: getaddrinfo не вдалося: Немає такого хоста невідомо. у деяких \ file \ шлях у рядку 6 ”насправді є кращим повідомленням про помилку. Це дає вам місце та причину проблеми. Ви можете заскочити прямо і почати налагодження, оскільки помилка вже знайдена.

Звичайно, дизайнери бібліотек іноді мають тенденцію викликати багато невідповідних попереджень. Я не знаю PHP достатньо добре, щоб знати, чи є у нього спосіб відфільтрувати попередження, які вас не цікавлять. Я знаю, що читання сторядкових стек-треків не дуже просвічує. Але правильна відповідь на занадто багато інформації полягає не в тому, щоб зменшити обсяг інформації до нуля , а на фільтруванні невідповідних частин на якомусь етапі. @Оператор не має таку зернистість (це девіз : все або нічого ), і тому не є підходящим інструментом для ефективного управління помилками.

Є деякі випадки , коли ви знаєте , що деяка помилка буде з'являтися, і фіксуючи актуальною проблемою є більш дорогим , ніж глушників повідомлення (і страждає потенційні радіоактивні опади від цього). Це може бути справа в одноразовому сценарії, але встромляти пальці у вуха і переходити « ля-ля-ла » - це не професійна відповідь на (потенційні) помилки.


5
Ви не хочете повідомляти своїм користувачам точну помилку. Ви повідомляєте їм, що помилка на вашому боці, і що ви працюєте над нею. Ви можете записати помилки на своєму сервері та налаштувати сповіщення, щоб ви про них автоматично знали, але немає жодних причин показувати ці помилки користувачеві.
Jeroen Vannevel

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

3
@Paradoxical На серйозному сайті ви б не відображали повідомлення про помилку типу "помилка бази даних" та нічого іншого. Ви б показали загальну сторінку "внутрішня помилка сервера" з великою кількістю зайвого пуху, стилів, колонтитулів тощо, яка dieне підходить ні для одного. І детальна інформація повинна надходити в журнал незалежно від того, що ви показуєте користувачеві .

1
Чи немає способу представити на екрані зручне повідомлення та написати технічне повідомлення у файл журналу?
FrustratedWithFormsDesigner

3
display_errorsвимкнено, log_errorsувімкнено, і вам дуже добре йти, робіть, як завгодно, виявляючи помилку, але не кидайте їх.
Wrikken

0

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

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

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


0

Так, оператор придушення помилок, як правило, погана ідея.

Вам слід керувати повідомленнями про помилки в конфігурації ( php.ini). Таким чином, ви можете вибрати інше налаштування для кожного середовища (наприклад, залиште попередження щодо розвитку та заховайте їх у виробництві).

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

Я не можу придумати жодного іншого використання.

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