2015-02-09 103 views
7

我有這樣的代碼:無法捕捉的symfony FatalErrorException

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

我當然有交際的變量和方法。這只是示範。

因此,如果我的集合是空的Collection :: first()將返回false。然後,getItem調用將拋出一個Symfony \ Component \ Debug \ Exception \ FatalErrorException,這將不會被上面的代碼捕獲。

我的問題是,我怎麼能發現這個異常?我有很多像這樣的鏈,可以返回null的許多getter。所以我更喜歡這種方式,而不是檢查每個值爲null。

+0

你試圖趕上(\ FatalErrorException) – Rooneyl 2015-02-09 09:37:27

+0

我試着趕上(Symfony的\分量\調試\異常\ FatalErrorException)和catch(\ ErrorException)。 – Jumi 2015-02-09 11:58:04

回答

8

正如您所見,here,FatalErrorException擴展了ErrorException(PHP),該類擴展自己的php Exception類。現在你已經擁有了所有這些元素,你可以爲下一步做好準備了:正如異常的名字所說,這是一個FatalError(一個與PHP相關的概念,而不是Symfony2;在這種情況下,他們構建了一個包裝類對於這個錯誤,也許是爲了接口的目的)。

一個PHP致命錯誤是不是開捕之一,所以沒什麼用,以保持可能導致即FatalError的代碼,try ... catch

您應該檢查,作爲公共和良好的規則裏面,只要是可能的在嘗試訪問它們之前返回值。

+0

您是否瞭解與默認樹枝過濾器具有相似功能的工具? – Jumi 2015-02-10 12:40:04

+0

@Jumi:你是什麼意思? – DonCallisto 2015-02-10 12:42:33

+0

我的意思是這樣的:http://twig.sensiolabs.org/doc/filters/default.html – Jumi 2015-02-11 09:34:03

1

好的。我找到了一個解決方法。我使用引發簡單異常的屬性訪問器組件,而不是致命錯誤。

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

使用邏輯/控制流的異常是一個壞主意。我希望你不會把上面的代碼塊放到任何生產環境中。 – 2015-02-09 22:19:01

+1

@RaduMurzea其實它是一種非常常見的Python語言之類的語言,他們表達爲「容易獲得寬恕而不是權限」。 (請參閱https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Exceptions) – richard 2015-06-18 06:11:29

-2

你可以試試這個:我

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

作品(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

5

使用Throwable的類,而不是異常類:

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

由於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