我如何记录一个没有用try/catch语句捕获的间歇性错误?


How can I log an intermittent error that is not caught with a try/catch statement?

我的下载脚本中有一个间歇性错误,我无法用try/catch捕获或以任何可靠性重现。在渲染时,我的500 Internal Error页面会将发生的错误记录到系统中。下面是抛出错误的代码块(如下面的日志所示)。

$logger->addDebug("User downloading widget", $dl);
header('Content-Description: File Transfer');
header('Content-type: application/octet-stream');
header('Content-length: '.filesize($dl['url']));
header('Content-Disposition: attachment; filename="'.str_replace('"', '_', $dl['name']).'"');
readfile($dl['url']);
exit();

包裹在它周围的try/catch块:

} catch (Exception $e) {
    $logger->addCritical('DOWNLOAD ERROR ENCOUNTERED', array (
        errorMessage => $e->getMessage()
    ));

我的日志显示如下。注意,第二个日志来自我的500.php,而不是catch块中的日志。

[2015-09-27 13:21:15] Site DEBUG: User downloading widget { ... }
[2015-09-27 13:21:16] Site CRITICAL: 500 INTERNAL SERVER ERROR { ... }

Apache/PHP也被配置为记录错误,但是这些日志中没有匹配任何事件的相关错误。

$dl['url']是存在于磁盘上的有效文件位置。$dl['name']是一个严格控制的文件名值,存在并且只有字母数字(替换只是一种安全措施)。在浏览器中使用确切的URL(以及击中该代码块的情况),我没有得到错误。

我把它包装在一个try/catch块中,它只是试图记录错误,但我没有从中得到任何日志结果,即使我仍然得到500个错误日志。现在我想我需要一个更一般的方法来得到这个误差。是否有一种方法在500错误页面(如.htaccess中设置的)上获得触发该页面的服务器错误?或者,是否有一个try/catch块(它只是记录错误)不工作的原因?

您无法捕获异常很可能是因为没有异常。只是一个错误。

500错误页面没有任何关于导致它显示的错误的信息。但是有多种方法可以显示或记录错误:

  1. 如果它不是生产站点,那么只需在输出中启用显示错误。您可以在php.ini.htaccess或PHP脚本中执行此操作。搜索error_reportingdisplay_errors

  2. 如果它是生产站点,您不应该向用户显示错误,所以启用错误记录。这些设置搜索"log_errors"answers"error_log"。这些设置也可以在php.ini.htaccess或PHOP脚本中设置。我建议你将它们设置在php.ini.htaccess

  3. 您可以实现并设置一个自定义错误处理程序,这只是一个回调函数,当PHP发生错误时调用它。在这个函数中,你有关于错误的所有信息(文件、行、消息、错误号等),你可以在那里做任何你想做的事情。例如,你可以实现自定义错误日志。

注意:如果您通过调用函数在PHP脚本中设置了任何这些设置,并且脚本中有语法错误,因此实际上无法解析和执行,这些函数将不会被执行,错误报告或日志将不会设置。因此最好配置在php.ini.htaccess