2015-02-09 11 views
7

mam kod jak poniżej:nie może złapać symfony FatalErrorException

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

Oczywiście mam nazwy zmiennych i metod komunikacyjnych. To tylko demonstracja.

Jeśli moja kolekcja jest pusta, Kolekcja :: first() zwróci wartość false. Następnie wywołanie getItem rzuci wyjątek Symfony \ Component \ Debug \ Exception \ FatalErrorException, który nie zostanie przechwycony przez powyższy kod.

Moje pytanie brzmi: jak mogę złapać ten wyjątek? Mam długie łańcuchy w ten sposób z wieloma pobierającymi, które mogą zwrócić wartość null. Więc wolę ten sposób, niż sprawdzanie każdej wartości dla wartości zerowej.

+0

próbowałeś złapać (\ FatalErrorException) – Rooneyl

+0

Próbowałem catch (Symfony \ Komponent \ Debug \ Wyjątek \ FatalErrorException) i zaczep (\ ErrorException). – Jumi

Odpowiedz

8

Jak widać here, wyjątek FatalErrorException rozszerza się o ErrorException (PHP), który rozszerza się o klasę php Exception.

Teraz, gdy masz już wszystkie te elementy, jesteś gotowy na następny krok: jak nazwa wyjątku mówi, jest to FatalError (pojęcie związane z PHP, a nie z Symfony2 - w tym przypadku zbudowali klasę opakowania dla tego błędu, może dla celów interfejsu).

PHP błąd krytyczny nie jest połów jeden więc jest całkiem bezużyteczny, aby zachować kod, który może spowodować, że FatalError wewnątrz bloku try ... catch

należy sprawdzić, jak i wspólnej dobrej zasady, ilekroć jest to możliwe dla zwróconych wartości, zanim spróbujesz uzyskać do nich dostęp.

+0

Czy wiesz o narzędziu, które ma podobne funkcje do domyślnego filtra gałązkowego? – Jumi

+0

@Jumi: co masz na myśli? – DonCallisto

+0

Mam na myśli coś takiego: http://twig.sensiolabs.org/doc/filters/default.html – Jumi

1

Ok. Znalazłem obejście. Używam komponentu właściwości właściwości, który zgłasza proste wyjątki, a nie błędy krytyczne.

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

Używanie wyjątków w logice/kontroli przepływu jest złym pomysłem. Mam nadzieję, że nie prześlesz bloków kodu, jak ten powyżej, do dowolnego środowiska produkcyjnego. –

+1

@RaduMurzea W rzeczywistości jest to bardzo powszechny wzorzec w niektórych językach, takich jak Python, gdzie wyrażają go jako "Łatwiej jest prosić o przebaczenie niż pozwolenie". (patrz: https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Exceptions) – richard

-2

można spróbować to:

$foo = $object->getCollection()->first(); 
if($foo){ 
    $var = $foo->getItem()->getName(); 
} else { 
    // fallback 
} 
0

pracuje dla mnie (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; 
} 

wyjściowa:

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

5

Użyj Throwable klasa zamiast Wyjątek klasa:

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

Od PHP 7.0 wyjątki rzucane od błędów krytycznych i odzyskane są przypadki nowej, odrębnej klasy wyjątek: Error. Ta nowa klasa Error implementuje interfejs Throwable, który określa metody prawie identyczne z tymi z Exception. Ponieważ Throwable jest wyżej w hierarchii, możesz złapać za jej pomocą zarówno \ Błąd, jak i \ Wyjątek.

interface Throwable 
|- Exception implements Throwable 
    |- ... 
|- Error implements Throwable 
    |- TypeError extends Error 
    |- ParseError extends Error 
    |- ArithmeticError extends Error 
     |- DivisionByZeroError extends ArithmeticError 
    |- AssertionError extends Error 
Powiązane problemy