如何记录未通过try / catch语句捕获的间歇性错误?

I have an intermittent error in my download script that I can't catch with a try/catch or reproduce with any sort of reliability. My 500 Internal Error page, upon rendering, logs to my system that it occurred. Here's the code block that seems to be throwing the error (as indicated by the logs below).

$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();

The try/catch block that is wrapped around it:

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

My logs shows the following. Note the second log is one from my 500.php and is not the log in the catch block there.

[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 is configured to log errors as well, but there are no relevant errors in those logs that match any event.

$dl['url'] is a valid file location that exists on disk. $dl['name'] is a tightly controlled filename value that exists and is alphanumeric only (the replace is simply a safety measure). Using the exact URL in the browser (and circumstances to hit this code block) I do not get the error.

I've wrapped this in a try/catch block which simply tries to log the error, but am not getting any logs results from it, even though I still get the 500 error log. So now I think I need a more general way to get this error. Is there a way on a 500 error page (as set in .htaccess) to get the server error that triggered the page? Or, alternatively, is there a reason why a try/catch block (which simply would log the error) is not working?

You're not able to catch an exception most probably because there is no exception. Just an error.

The 500 error page doesn't have any information about an error which caused it to display. But there are multiple ways to display or log an error:

  1. If it's not a production site, then just enable displaying of errors in the output. You can do it in php.ini, .htaccess or in your PHP scripts. Search for error_reporting and display_errors.

  2. If it's production site, you shouldn't display errors to the users, so enable error logging instead. These settings Search for log_errors and error_log. These settings can be also set in php.ini, .htaccess or in your PHOP scripts. I would advice you to set them in php.ini or .htaccess.

  3. You can implement and set a custom error handler, which is simply a callback function, which is called whenever PHP error happens. In this function you have all information about an error (file, line, message, error number etc.) and you can do whatever you want there. So you can for example implement you custom error logging.

Note: If you set any of these settings in your PHP script by calling a function(s) and there is a syntax error somewhere in the script, so it actually cannot be parsed and executed, these functions won't be executed and error reporting or logging won't be set. Therefore it's better to configure it in php.ini or .htaccess.