Ошибка подавляет плохую практику?


14

На один вопрос, который я задал здесь о некотором коде, в котором я не был уверен, кто-то ответил: «Кстати, ужасный код: он часто использует символ подавления ошибок (@)».

Есть ли причина, почему это плохая практика? С такими вещами, как:

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

, это позволяет мне отображать только пользовательское сообщение об ошибке. Без подавления ошибок он все равно будет отображать типичное сообщение PHP:

Предупреждение : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo не удалось: такой хост не известен. в какой-то \ файл \ путь в строке 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 \ path on line 6 ”на самом деле лучшее сообщение об ошибке. Это дает вам место и причину проблемы. Вы можете сразу же приступить к отладке, поскольку ошибка уже обнаружена.

Конечно, разработчики библиотек иногда склонны приводить ко многим не относящимся к делу предупреждениям. Я не знаю PHP достаточно хорошо, чтобы знать, есть ли у него способ отфильтровывать предупреждения, которые вас не интересуют. Я знаю, что чтение через трассировку стека из ста строк не очень полезно. Но правильный ответ на слишком большое количество информации заключается не в том, чтобы уменьшить количество информации до нуля , а в том, чтобы отфильтровать несущественные части на некотором этапе. @Оператор не имеет такую зернистость (это девиз : все или ничего ), и поэтому не является подходящим инструментом для эффективного управления ошибками.

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


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

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.