无法捕获 symfony FatalErrorException
Can't catch symfony FatalErrorException
我有这样的代码:
try {
$var = $object->getCollection()->first()->getItem()->getName();
} catch(\Exception $e) {
$var = null;
}
我当然有可交流的变量和方法名称。这只是演示。
因此,如果我的集合为空,Collection::first() 将 return 为假。然后 getItem 调用将抛出一个 Symfony\Component\Debug\Exception\FatalErrorException,它不会被上面的代码捕获。
我的问题是我怎样才能捕捉到这个异常?我有像这样的长链,其中有许多可以 return null 的吸气剂。所以我更喜欢这种方式,而不是检查每个值是否为空。
如你所见here, FatalErrorException extends ErrorException (PHP) that extends itself php Exception class.
现在你已经有了所有这些元素,你已经准备好进行下一步了:正如异常的名称所说,这是一个 FatalError(一个与 PHP 相关的概念,而不是与 Symfony2 相关的概念;在那种情况下他们为这个错误构建了一个包装器 class,可能是出于接口目的)。
A PHP 致命错误不是可捕获的错误,因此将可能导致 FatalError 的代码保留在 try ... catch
块
中是非常无用的
作为一条通用且良好的规则,您应该在尝试访问返回值之前尽可能检查它们。
更新
因为我在 PHP7 发布后看到了对我的回答的赞成票,所以我想警告 since PHP7 is possible to catch fatal errors 所以这个答案是仍然有效,但仅适用于 PHP 版本 < 7。
好的。我找到了解决方法。我使用 属性 访问器组件,它抛出简单的异常,而不是致命错误。
$pa = \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor();
try {
$var = $pa->getValue($object, 'collection[0].item.name');
} catch(\Exception $e) {
$var = null;
}
适合我(PHP 7.0,Symfony 3.0.9):
use Symfony\Component\Debug\Exception\FatalThrowableError;
...
try {
throw new FatalErrorException("something happened!", 0, 1, __FILE__, __LINE__);
} catch (FatalErrorException $e) {
echo "Caught exception of class: " . get_class($e) . PHP_EOL;
}
输出:
Caught exception of class: Symfony\Component\Debug\Exception\FatalErrorException
使用 Throwable class 代替 Exception class:
try {
$var = $object->getCollection()->first()->getItem()->getName();
} catch(\Throwable $e) {
$var = null;
$msg = $e->getMessage();
}
自 PHP 7.0 起,致命错误和可恢复错误引发的异常是新的独立异常的实例 class:Error
。这个新的 Error
class 实现了 Throwable
接口,它指定的方法与 Exception
的方法几乎相同。因为 Throwable
在层次结构中更高,所以你可以同时捕获它,\Error 和 \Exception。
interface Throwable
|- Exception implements Throwable
|- ...
|- Error implements Throwable
|- TypeError extends Error
|- ParseError extends Error
|- ArithmeticError extends Error
|- DivisionByZeroError extends ArithmeticError
|- AssertionError extends Error
我有这样的代码:
try {
$var = $object->getCollection()->first()->getItem()->getName();
} catch(\Exception $e) {
$var = null;
}
我当然有可交流的变量和方法名称。这只是演示。
因此,如果我的集合为空,Collection::first() 将 return 为假。然后 getItem 调用将抛出一个 Symfony\Component\Debug\Exception\FatalErrorException,它不会被上面的代码捕获。
我的问题是我怎样才能捕捉到这个异常?我有像这样的长链,其中有许多可以 return null 的吸气剂。所以我更喜欢这种方式,而不是检查每个值是否为空。
如你所见here, FatalErrorException extends ErrorException (PHP) that extends itself php Exception class.
现在你已经有了所有这些元素,你已经准备好进行下一步了:正如异常的名称所说,这是一个 FatalError(一个与 PHP 相关的概念,而不是与 Symfony2 相关的概念;在那种情况下他们为这个错误构建了一个包装器 class,可能是出于接口目的)。
A PHP 致命错误不是可捕获的错误,因此将可能导致 FatalError 的代码保留在 try ... catch
块
作为一条通用且良好的规则,您应该在尝试访问返回值之前尽可能检查它们。
更新
因为我在 PHP7 发布后看到了对我的回答的赞成票,所以我想警告 since PHP7 is possible to catch fatal errors 所以这个答案是仍然有效,但仅适用于 PHP 版本 < 7。
好的。我找到了解决方法。我使用 属性 访问器组件,它抛出简单的异常,而不是致命错误。
$pa = \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor();
try {
$var = $pa->getValue($object, 'collection[0].item.name');
} catch(\Exception $e) {
$var = null;
}
适合我(PHP 7.0,Symfony 3.0.9):
use Symfony\Component\Debug\Exception\FatalThrowableError;
...
try {
throw new FatalErrorException("something happened!", 0, 1, __FILE__, __LINE__);
} catch (FatalErrorException $e) {
echo "Caught exception of class: " . get_class($e) . PHP_EOL;
}
输出:
Caught exception of class: Symfony\Component\Debug\Exception\FatalErrorException
使用 Throwable class 代替 Exception class:
try {
$var = $object->getCollection()->first()->getItem()->getName();
} catch(\Throwable $e) {
$var = null;
$msg = $e->getMessage();
}
自 PHP 7.0 起,致命错误和可恢复错误引发的异常是新的独立异常的实例 class:Error
。这个新的 Error
class 实现了 Throwable
接口,它指定的方法与 Exception
的方法几乎相同。因为 Throwable
在层次结构中更高,所以你可以同时捕获它,\Error 和 \Exception。
interface Throwable
|- Exception implements Throwable
|- ...
|- Error implements Throwable
|- TypeError extends Error
|- ParseError extends Error
|- ArithmeticError extends Error
|- DivisionByZeroError extends ArithmeticError
|- AssertionError extends Error