错误抑制不良做法吗?


14

在一个SO问题上,我在这里问了一些我不确定的代码,有人回答说:“ BTW,那里的代码很糟糕:它经常使用错误抑制符号(@)。”

有什么不好的做法吗?具有以下内容:

$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
在进行不良练习时是否戴着眼罩?
Damien Roche

这怎么可能是一个严肃的问题?我想,如果您想编写需要花费数小时才能调试的代码,那么抑制错误将是一件好事。考虑一下,您的应用程序失败,破坏了数据……并且您不想知道代码中的原因或位置。什么时候会是个好主意?您必须邀请您的朋友过来对您进行一揽子派对 ……它遵循相同的逻辑。
一些免费的梅森

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中的异常/错误处理状态有些不完善,但是您知道可以在PHP配置中关闭错误的可视显示,对吗?
Phoshi

@Phoshi不幸的是,我使用的托管服务无法使我访问php.ini

Answers:


14

我认为您通过抑制错误来做正确的事,因为您正在实现自己的错误处理。

例如,在Java中考虑等效项可能会更容易。使用抑制错误@类似于吞入异常。以下与您的代码相似的代码是合理的:

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

(嗯,在Java中,您不希望servlet引擎死掉,但您知道了。)

但是,这是不可接受的:

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

与后面的示例类似,大多数PHP错误抑制都是不小心进行的,因此会对您的代码产生下意识的反应。


3
我不会调用捕获异常,而只是停止执行来“处理”它。如果您能解决问题,那就太好了。如果不能,那么您到底在抓什么呢?这就是我们的顶级异常处理程序。在这种情况下,捕获异常只是确保您在整个代码库中散布了错误处理代码。
Phoshi

7

错误抑制是坏的,因为它不仅掩盖你已经知道的信息(什么地方出了错)。它还可能会隐藏对于调试不重要的信息(什么在哪里为什么)。

在此特定示例中,“ Database error ”不是一个很好的错误消息。数据库出了点问题。不太启发。“ 警告:mysqli :: mysqli():php_network_getaddresses:getaddrinfo失败:此类主机未知。在第6行的some \ file \ path中, “实际上是更好的错误消息。它为您提供了问题的位置和原因。您可以直接跳入并开始调试,因为错误已被发现。

当然,图书馆设计师有时倾向于提出许多不相关的警告。我对PHP不太了解,无法确定它是否具有过滤您不感兴趣的警告的方法。我知道通读一百行的stacktrace并不是很有启发性。但是,对过多信息的正确响应不是将信息量减少到,而是在某个阶段过滤掉不相关的部分。该@运营商不具有这种粒度(它的座右铭是全有或全无),因此不是有效的错误管理的合适工具。

有些情况下,你知道某个错误就会转起来,而且固定实际问题比沉默消息(并从痛苦可能导致的后果)更昂贵。一次性脚本可能就是这种情况,但是将手指伸入耳朵并“ 拉啦啦并不是对(潜在)错误的专业回应。


5
您不想告诉您的用户确切的错误。您通知他们错误就在您身边,并且您正在努力。您可以将错误记录在服务器上并设置警报,以便自动了解它,但是没有理由向用户显示这些错误。
Jeroen Vannevel

1
在实际站点上,显示一般用户可以理解的错误消息肯定会更好,而不是“关于mysqli的一些技术垃圾,无论如何”?如果我要调试它,则将删除错误抑制,但是在实际站点中,我不同意应显示完整的错误。

3
@Paradoxical在严重的网站上,您不会显示诸如“数据库错误”之类的错误消息,而不会显示其他任何内容。您将显示一个通用的“内部服务器错误”页面,其中包含许多多余的绒毛,样式,页脚等,这两个die都不适合。无论向用户显示什么内容,详细信息都应记入日志。

1
没有办法在屏幕上显示用户友好的消息并将技术消息写入日志文件吗?
FrustratedWithFormsDesigner

3
display_errors断断续续,log_errors然后您就可以很好地开始工作了,请按自己的意愿检测错误,但不要将其丢弃。
Wrikken

0

压制错误是很糟糕的,因为它隐藏了问题,很多时候我们甚至都没有意识到,它可能导致意外的行为,在某些关键应用程序中,例如在金融,健康和国防领域中使用的应用程序,其代价可能会非常高昂。

在代码中包含未处理的异常并向用户显示实际错误消息也不是一个好主意,因为这可能会导致安全问题,因为错误消息通常会泄露很多有关您的代码的信息,这可能有助于恶意用户和黑客进行操纵系统。

因此,好的做法是在不同级别上处理错误,例如,在最高级别上,您可以通过登录实际错误并向用户显示简单且用户友好的消息来处理错误。


0

是的,错误抑制运算符通常不是一个好主意。

您应该在配置(php.ini)中管理错误报告。因此,您可以为每种环境选择不同的设置(例如,在开发中保留警告,在生产中隐藏警告)。

使用时的唯一情况 @有意义的情况是为其他开发人员开发库。如果您自愿选择执行会产生警告的操作,并且不想以不依赖于他们的警告来惹恼您图书馆的用户,@可能是一个解决方案。

我没有其他用途。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.