2012-01-09 23 views
3

我建立了一個簡單的ExceptionHandler類:的ExceptionHandler不要再追所有捕獲的異常

class ExceptionHandler{ 

    public function __construct(){ 

     set_exception_handler(array($this, 'handleException')); 
    } 

    public function handleException(\Exception $exception){ 
     echo $exception->getMessage() . $exception->getLine() . $exception->getFile()); 

    } 
} 

ExceptionHandler對象的處理過程中儘早建立。使用數據庫存儲數據的會話組件在ExceptionHandler後不久構建。

會話單元設置以下正確關閉會話使用APC時:

register_shutdown_function('session_write_close'); 

我然後通過關閉我的MySQL服務器和運行應用程序進行測試。更令人不解的是,異常是由ExceptionHandler抓住了,但同時仍然未捕獲,並通過Xdebug的輸出:

SQLSTATE[HY000] [2002] ????,??????????? at line 133 in RedBean_Driver_PDO.php. //This is generated by my exception handler 

//These were uncaught and processed by Xdebug 
Fatal error: Uncaught exception 'Exception' with message 'PDO::__construct() [133 

(!) Exception: PDO::__construct() [pdo.--construct]: [2002] ????,??????????? (trying to connect via tcp://localhost:3306) in RedBean_Driver_PDO.php on line 133 

Call Stack 
//Call stack 

可能是什麼造成的?我的理解是ExceptionHandler應該能夠捕獲所有未捕獲的異常,除了在ExceptionHandler內引發的任何異常。

更新: 我有一種感覺,這必須處理session_write_close這是在關機時調用。 session_write_close需要訪問數據庫,但數據庫是不可避免的。然後拋出異常。由於腳本執行已結束,因此ExceptionHandler是不可避免的,所以我們得到未捕獲的異常。有沒有反正呢?

我在apache 2.2上使用mod_cgi在windows 7機器上運行php 5.3.9作爲fcgi。

堆棧跟蹤:

# Time Memory Function 
1 2.0323 767336 ExceptionHandler->handleException() //Initial exception caught + handled 
2 2.0334 773968 Session->write() //Script shutdown started (session_write_close to database) 
3 2.0335 774344 Database->findOne() 
4 2.0335 774640 Database->__call() 
5 2.0335 774728 call_user_func_array() 
6 2.0335 775016 RedBean_Facade::findOne() 
7 2.0335 775016 RedBean_Facade::find() 
8 2.0335 775384 RedBean_OODB->find() 
9 2.0335 775384 RedBean_QueryWriter_AQueryWriter->selectRecord() 
10 2.0335 775448 RedBean_QueryWriter_AQueryWriter->safeTable() 
11 2.0335 775536 RedBean_QueryWriter_AQueryWriter->check() 
12 2.0335 775536 RedBean_Adapter_DBAdapter->escape() 
13 2.0335 775536 RedBean_Driver_PDO->Escape() 
14 2.0335 775536 RedBean_Driver_PDO->connect() 
15 2.0336 776200 PDO->__construct() //Cannot connect to database 
16 4.0433 782768 ErrorHandler->handleError() //Error converted to exception 

我有一種感覺,這不能真正避免,並在生產環境display_errors無論如何都會被關閉。然而,我並不完全滿意這個解決方案,因爲它似乎不是很「乾淨」。

+0

這可能不是解決您的問題,但你可能會試圖糾正這個代碼'$ exception->的GetFile()); '通過刪除空格,以便它讀取'$ exception-> getFile());' – rdlowrey 2012-01-09 02:19:11

+0

將try/catch中的有問題的代碼包裝起來,並檢查拋出PDO異常時當前的異常處理程序是什麼。也許其他組件重置你背後的異常處理程序? – Jon 2012-01-09 02:28:24

+0

@rdlowrey:修復它,雖然這只是我寫這個問題時的一個錯字。 @Jon:試圖將代碼包裝在try/catch中,並能夠使異常消失。檢查了異常處理程序,它仍然是正在使用的「ExceptionHandler」。我已明確將'exit()'添加到'handleException()'中,但似乎這些未捕獲的異常仍然在exit()後輸出! – F21 2012-01-09 02:42:02

回答

1

你不能在PHP中發現致命的異常。可悲!註冊一個關閉功能,刷新輸出緩衝區是你所能做的。既然你已經有一個關機功能,那麼那裏有東西會導致這個問題。我想試試這個:

// This must be called before any code is executed 
register_shutdown_function('shutdownFunction'); 

function shutdownFunction() { 
    // process code - be careful not to throw another fatal exception 
    try { 
     call_user_func('session_write_close'); 
    } catch() {} 
    ob_clean(); 
} 

...以外,我認爲你堅持