2011-10-21 25 views
10

में अपवाद फेंकना मेरे पास अपवाद हैंडलर वाला एक स्क्रिप्ट है। अपवाद के बाद बाहर निकलने वाली स्क्रिप्ट से पहले, यह अपवाद हैंडलर कुछ कनेक्शन साफ़ करता है।अपवाद हैंडलर

मैं इस अपवाद हैंडलर से अपवाद को फिर से फेंकना चाहता हूं ताकि इसे PHP के अपने अंतिम-रिज़ॉर्ट अपवाद हैंडलर द्वारा संभाला जा सके, जहां त्रुटि PHP के त्रुटि लॉग, या जो भी डिफ़ॉल्ट है, में कॉन्फ़िगर किया गया है php.ini।

दुर्भाग्य से, यह, एक संभावना की तरह प्रतीत नहीं होता है के रूप में यहां उनका उल्लेख:

http://www.php.net/manual/en/function.set-exception-handler.php#68712

Will cause a Fatal error: Exception thrown without a stack frame

वहाँ बुलबुला का एक और तरीका त्रुटि ढेर ऊपर है तो पीएचपी मेरी अपवाद के बाद यह संभालती है कि हैंडलर सफाई कर रहा है?

+0

रखेंगे एक कस्टम अपवाद संचालक का प्रयोग अभी भी एक घातक erro ट्रिगर किया जाएगा आर और इस प्रकार त्रुटि लॉग इन करें। – netcoder

+0

आप अपने हैंडलर से क्यों नहीं [बस अपवाद फेंक दें] (http://stackoverflow.com/questions/7856173/throwing-exception-within-exception-handler/7939492#7939492)? यह काम करता है अगर आप जानते हैं कि कैसे। और यह आपके द्वारा देखे जा रहे अंतिम रिज़ॉर्ट हैंडलर को ट्रिगर करेगा। – hakre

+0

मैंने इसे पहले देखा है (और त्रुटि हैंडलर को बहाल करने की अनुशंसा करेगा) लेकिन मैं अभी पुन: पेश नहीं कर सकता! क्या यह मुद्दा PHP/.ini सेटिंग्स के संस्करण के आंशिक है? – jlb

उत्तर

12

आप अपवाद हैंडलर से फिर से फेंक नहीं सकते हैं, हालांकि, आप अन्य स्थान भी कर सकते हैं। उदाहरण के लिए आप अपने आप के एक वर्ग में चीजों को encapsulating द्वारा डी-जोड़ी कर सकते हैं हैंडलर से फिर से फेंक और फिर __destruct() समारोह (पीएचपी 5.3, Demo) का उपयोग करें:

<?php 

class ExceptionHandler 
{ 
    private $rethrow; 
    public function __construct() 
    { 
     set_exception_handler(array($this, 'handler')); 
    } 
    public function handler($exception) 
    { 
     echo "cleaning up.\n"; 
     $this->rethrow = $exception; 
    } 
    public function __destruct() 
    { 
     if ($this->rethrow) throw $this->rethrow; 
    } 
} 

$handler = new ExceptionHandler; 

throw new Exception(); 

मेरी त्रुटि लॉग में इस रखो:

[29-Oct-2011 xx:32:25] PHP Fatal error: Uncaught exception 'Exception' in /.../test-exception.php:23 
Stack trace: 
#0 {main} 
thrown in /.../test-exception.php on line 23 
+1

साथ ही देखें, जो कि '__destruct' के बारे में कुछ हद तक संबंधित है: [यह निर्धारित करने के लिए कि एक PHP स्क्रिप्ट समाप्ति चरण में है?] (Http://stackoverflow.com/q/6227611/367456) – hakre

+0

धन्यवाद @ hakre, आपका समाधान काम करता है। मैं उम्मीद कर रहा था उससे अधिक कामकाज, लेकिन मुझे समझ में आता है कि यह क्यों जरूरी है। – Brad

+0

हे ब्रैड, स्वीकृति के लिए धन्यवाद। मुझे php.net पर उपयोगकर्ता-टिप्पणियों पर सुझाव के मुकाबले इस "वर्कअराउंड" को पसंद है ताकि वे स्वयं लॉग इन एंट्री बना सकें। पहिया का फिर से आविष्कार क्यों करें? मैंने पंजीकरण शट डाउन फ़ंक्शन के साथ भी कोशिश की, लेकिन यह एक मुझे बेहतर पसंद है। – hakre

6

बस अपवाद पकड़ें और संदेश को स्वयं लॉग करें, फिर पुन: प्रयास करें।

try { 
    $foo->doSomethingToCauseException(); 
} catch (Exception $e) { 
    error_log($e->getMessage()); 
    throw $e; 
} 

यदि आप शीर्ष पर बबल करते हैं और PHP संभाल नहीं पाता है, तो इसका परिणाम अपरिचित अपवाद नहीं होगा।

+0

मेरे साथ एक अपवाद अपवाद ठीक होगा। मैं ऊपर तक सभी को बुलबुला करना चाहता हूं।मैं अभी खुद को लॉगिंग करने में त्रुटि कर रहा हूं (सटीक विधि का उपयोग करके आप वर्णन कर रहे हैं), लेकिन इसके बजाय PHP को स्थिरता के लिए इसे संभालने देना होगा। – Brad

+0

मैं देखता हूं। मैं इसके बारे में भी उत्सुक हूं। मेरे अनुभव में PHP एकमात्र तरीका अपवादों को संभालता है जिससे पृष्ठ विस्फोट हो जाता है, lol। –

3

Will cause a Fatal error: Exception thrown without a stack frame

यह त्रुटि का अर्थ है कि आपका अपवाद उस कोड से फेंक दिया गया है जो स्क्रिप्ट का हिस्सा नहीं है (जहां तक ​​PHP जानता है)। इस तरह के कोड के उदाहरणों में कस्टम अपवाद हैंडलर सेट set_exception_handler() और किसी भी वर्ग विनाशक विधि के साथ सेट है। इस तरह के कोड से अपवाद फेंकने के अलावा कोई विकल्प नहीं है।

यदि आप PHP मूल त्रुटि प्रबंधन चाहते हैं, तो मैं आपको इसके बजाय trigger_error() पर कॉल करने का सुझाव दूंगा। यदि आपके पास कस्टम त्रुटि हैंडलर नहीं है और आप उपयुक्त त्रुटि प्रकार का उपयोग करते हैं तो इसे त्रुटि लॉग करनी चाहिए। उदाहरण के लिए, E_USER_ERROR ठीक होना चाहिए।

+0

या [बस अपवाद फेंक दें] (http://stackoverflow.com/questions/7856173/throwing-exception-within-exception-handler/7939492#7939492) जो कॉन्फ़िगरेशन के आधार पर उचित बैकट्रैक देगा। – hakre

+0

hakre: बस इसे आज़माएं (कस्टम अपवाद हैंडलर या कक्षा विनाशक विधि के अंदर से * कुछ भी * फेंक दें) - आप पाएंगे कि यह काम नहीं करता है। इससे कोई फर्क नहीं पड़ता कि आप xdebug का उपयोग करते हैं या नहीं। –

+1

मिक्को, [मेरा जवाब] जैसा दिखता है (http://stackoverflow.com/questions/7856173/throwing-exception-within-exception-handler/7939492#7939492) PHP 5.3 की आवश्यकता है। साथ ही देखें http://codepad.viper-7.com/jamrqP – hakre

0

http://www.php.net/manual/en/function.set-exception-handler.php#88082 से मैंने पढ़ा: एक और समाधान अपवाद हैंडलर की शुरुआत में त्रुटि हैंडलर को पुनर्स्थापित करना है। क्या आपने इसे आजमाया है?

+0

यह काम नहीं करता है, क्षमा करें। 'Restore_exception_handler()' का अपवाद के भीतर कोई प्रभाव नहीं पड़ता है। – Brad

1

बस एक RunTimeException के रूप में अपवाद rethrow और यह स्टैकट्रेस :)

try { 
    // bad exception throwing code 
} catch (Exception $e) { 
    throw new RuntimeException($e->getMessage(), $e->getCode(), $e); 
} 
संबंधित मुद्दे