无法捕获symfony FatalErrorException

Jum*_*umi 29 php exception-handling symfony

我有这样的代码:

try {
    $var = $object->getCollection()->first()->getItem()->getName();
} catch(\Exception $e) {
    $var = null;
}
Run Code Online (Sandbox Code Playgroud)

当然,我有交际变量和方法名称.这只是示范.

因此,如果我的集合为空,则Collection :: first()将返回false.然后getItem调用将抛出一个Symfony\Component\Debug\Exception\FatalErrorException,它不会被上面的代码捕获.

我的问题是我怎么能抓住这个例外?我有这样的长链,有许多可以返回null的getter.所以我更喜欢这种方式而不是检查null的每个值.

J.C*_*ras 55

使用Throwable类而不是Exception类:

try {
    $var = $object->getCollection()->first()->getItem()->getName();
} catch(\Throwable $e) {
    $var = null;
    $msg = $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)

因为从致命和可恢复错误抛出的PHP 7.0异常是新的和单独的异常类的实例:Error.这个新Error类实现了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
Run Code Online (Sandbox Code Playgroud)

  • 我可以确认这解决了问题,但我不明白为什么。Symfony 的 `FatalErrorException` 扩展了 `\ErrorException`,它扩展了 `\Exception`。PHP 现在将 `Error` 作为基类的事实似乎并不相关,因为它不在 `FatalErrorException` 的继承层次结构中。有人可以解释一下吗? (4认同)

Don*_*sto 13

正如你在这里看到的,FatalErrorException扩展了自己扩展php 异常类的ErrorException(PHP).

现在您已经拥有了所有这些元素,您已准备好进行下一步:正如异常名称所示,这是一个FatalError(与PHP相关的概念而不是Symfony2;在这种情况下,他们为此错误构建了一个包装类,也许是出于界面目的).

PHP致命错误不是一个可捕获的错误,因此在try ... catch块内保留可能导致FatalError的代码是没有用的

作为一个常见且良好的规则,您应该在尝试访问它们之前检查返回值.


Jum*_*umi 0

好的。我找到了解决方法。我使用属性访问器组件,它抛出简单的异常,而不是致命错误。

$pa = \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor();
try {
    $var = $pa->getValue($object, 'collection[0].item.name');
} catch(\Exception $e) {
    $var = null;
}
Run Code Online (Sandbox Code Playgroud)

  • @RaduMurzea 实际上,这是 Python 等某些语言中非常常见的模式,他们将其表达为“请求宽恕比请求许可更容易”。(参见 https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Exceptions) (5认同)
  • 对逻辑/控制流使用异常是一个坏主意。我希望您不要将上述代码块发送到任何生产环境中。 (2认同)