web-dev-qa-db-fra.com

Impossible d'attraper symfony FatalErrorException

J'ai un code comme ça:

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

Bien sûr, j'ai des noms de variables et de méthodes de communication. Ceci est juste une démonstration.

Donc si ma collection est vide, Collection :: first () retournera false. Ensuite, l'appel getItem lancera une exception Symfony\Component\Debug\Exception\FatalErrorException qui ne sera pas interceptée par le code ci-dessus.

Ma question est la suivante: comment puis-je attraper cette exception? J'ai de longues chaînes comme celle-ci avec beaucoup de getters qui peuvent renvoyer null. Donc, je préfère cette façon plutôt que de vérifier chaque valeur pour null.

21
Jumi

D'accord. J'ai trouvé une solution de contournement. J'utilise le composant d'accès de propriété qui génère des exceptions simples et non des erreurs fatales.

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

Utilisez Throwable class à la place Exception class:

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

Depuis PHP 7.0, les exceptions générées par des erreurs fatales et récupérables sont des instances d'une nouvelle classe d'exceptions distincte: Error. Cette nouvelle classe Error implémente l'interface Throwable, qui spécifie des méthodes presque identiques à celles de Exception. Parce que Throwable est plus haut dans la hiérarchie, vous pouvez attraper avec elle,\Error et\Exception.

interface Throwable
|- Exception implements Throwable
    |- ...
|- Error implements Throwable
    |- TypeError extends Error
    |- ParseError extends Error
    |- ArithmeticError extends Error
        |- DivisionByZeroError extends ArithmeticError
    |- AssertionError extends Error
36
J.C. Gras

Comme vous pouvez le voir ici , FatalErrorException étend ErrorException (PHP) qui s’étend lui-même php Exception class.

Maintenant que vous avez tous ces éléments, vous êtes prêt pour l’étape suivante: comme le nom de l’exception le dit, il s’agit d’une erreur FatalError (concept lié à PHP et non à Symfony2; dans ce cas, ils ont construit une classe wrapper pour cette erreur, peut-être à des fins d'interface).

Une erreur fatale PHP n'est pas une erreur capturable, il est donc plutôt inutile de conserver le code qui pourrait causer FatalError, à l'intérieur d'un bloc try ... catch

Avant de tenter d'y accéder, vous devez vérifier, en règle générale, s'il est possible que les valeurs retournées soient possibles.

13
DonCallisto

Fonctionne pour moi (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;
}

Sortie:

Caught exception of class: Symfony\Component\Debug\Exception\FatalErrorException

0
iloo