尽管使用 try/catch 块,但为什么 PHP 抛出致命错误并中断 HTTP 500?
Why does PHP throw fatal errors and break with HTTP 500 although using try/catch blocks?
在我的 AWS 日志中,我有这样的条目:
[Wed Feb 06 10:12:22.306730 2019] [php7:error] [pid 28445] [client
172.31.10.7:55646] PHP Fatal error: Uncaught Error: Class 'comet_cache' not found in
/var/app/current/project-website-wordpress/wp-content/mu-plugins/comet-cache-ec2-enabler.php:41
当某些特定的 HTTP 500 请求发生时,会记录这些条目。
检查代码后,我发现了以下内容(在提到的文件的第 41 行):
try {
comet_cache::clear();
} catch(Exception $e) {
// if comet cache is not activated, we want to continue anyway
}
这基本上是有道理的 - 似乎没有找到 class,但如果是这种情况,应该继续执行。为什么 PHP 停止?
你没有接住,因为你想接住 \Exception
,但抛出的是 \Error
.
考虑到您的错误消息,我会说您正在使用 PHP >= 7(您应该具体说明,错误处理已从版本 5 到版本 显着 7).
在 PHP >= 7,most fatal errors are reported not by raising an error, but by throwing an Error
object。
所以你的陈述可以重写为:
try {
$a = new ClassNotFindable();
}
catch (\Error $e) {
// do your catching
}
此外,Error
和 Exception
类 都实现了 Throwable
接口,因此您可以直接捕获它:
<?php
try {
$a = new NotFound();
}
catch (\Throwable $t) {
echo "caught!\n";
echo $t->getMessage(), " at ", $t->getFile(), ":", $t->getLine(), "\n";
}
您可以看到它正在运行 here。
这与 AWS 没有任何关系,只是 PHP 的事情。如果您使用 PHP < 7 它仍然不会被捕获,但在那种情况下因为常见错误不会抛出异常。
如果您使用的是 PHP5,为了能够将错误捕获为异常,您需要设置自定义错误处理程序。 example in the manual 似乎很合适:
function exception_error_handler($severidad, $mensaje, $fichero, $línea) {
if (!(error_reporting() & $severidad)) {
// Este código de error no está incluido en error_reporting
return;
}
throw new ErrorException($mensaje, 0, $severidad, $fichero, $línea);
}
set_error_handler("exception_error_handler");
在我的 AWS 日志中,我有这样的条目:
[Wed Feb 06 10:12:22.306730 2019] [php7:error] [pid 28445] [client 172.31.10.7:55646] PHP Fatal error: Uncaught Error: Class 'comet_cache' not found in /var/app/current/project-website-wordpress/wp-content/mu-plugins/comet-cache-ec2-enabler.php:41
当某些特定的 HTTP 500 请求发生时,会记录这些条目。
检查代码后,我发现了以下内容(在提到的文件的第 41 行):
try {
comet_cache::clear();
} catch(Exception $e) {
// if comet cache is not activated, we want to continue anyway
}
这基本上是有道理的 - 似乎没有找到 class,但如果是这种情况,应该继续执行。为什么 PHP 停止?
你没有接住,因为你想接住 \Exception
,但抛出的是 \Error
.
考虑到您的错误消息,我会说您正在使用 PHP >= 7(您应该具体说明,错误处理已从版本 5 到版本 显着 7).
在 PHP >= 7,most fatal errors are reported not by raising an error, but by throwing an Error
object。
所以你的陈述可以重写为:
try {
$a = new ClassNotFindable();
}
catch (\Error $e) {
// do your catching
}
此外,Error
和 Exception
类 都实现了 Throwable
接口,因此您可以直接捕获它:
<?php
try {
$a = new NotFound();
}
catch (\Throwable $t) {
echo "caught!\n";
echo $t->getMessage(), " at ", $t->getFile(), ":", $t->getLine(), "\n";
}
您可以看到它正在运行 here。
这与 AWS 没有任何关系,只是 PHP 的事情。如果您使用 PHP < 7 它仍然不会被捕获,但在那种情况下因为常见错误不会抛出异常。
如果您使用的是 PHP5,为了能够将错误捕获为异常,您需要设置自定义错误处理程序。 example in the manual 似乎很合适:
function exception_error_handler($severidad, $mensaje, $fichero, $línea) { if (!(error_reporting() & $severidad)) { // Este código de error no está incluido en error_reporting return; } throw new ErrorException($mensaje, 0, $severidad, $fichero, $línea); } set_error_handler("exception_error_handler");