अपवाद से निपटने का सही तरीका क्या है?


20

जूमला कोर में मुझे अभी भी इस तरह के कई कॉल मिलते हैं:

    // Check for errors.
    if (count($errors = $this->get('Errors')))
    {
        JError::raiseError(500, implode("\n", $errors));
        return false;
    }

लेकिन JError को प्लेटफ़ॉर्म रिलीज़ 12.1 के बाद से हटा दिया गया है। तो मुझे मानक PHP अपवादों का उपयोग कैसे करना चाहिए।


1
यह अंतर JError से PHP त्रुटियों की ओर बढ़ रहा है दुर्भाग्य से बस एक क्लिक प्रक्रिया नहीं है। इसलिए यदि आप सुनिश्चित हैं कि आप एक अपवाद प्राप्त करने जा रहे हैं, तो नीचे दिए गए उत्तर के अनुसार एक प्रयास करें / पकड़ें। अगर आपको यकीन है कि आपको एक JError मिलने वाली है, तो आपको उपरोक्त कोड के समान कोड करने की आवश्यकता है :)
जॉर्ज विल्सन

जवाबों:


17

@DmitryRekun ने कहा, एक अच्छी चर्चा यहाँ है । इस सब पर विचार करने के लिए महत्वपूर्ण टुकड़ा आपके पास किस प्रकार की त्रुटि है?

त्रुटियों के दो प्रकार हैं:

  1. बचानेवाला
  2. अप्राप्य।

अंतर मैं इस प्रकार है:

Can I still show the page that was requested, even though this error occurred?
  • हाँ? - पुनर्प्राप्त करने योग्य
  • नहीं? - अपरिवर्तनीय

अब जब हम जानते हैं कि हम किसके साथ काम कर रहे हैं। आपको क्या करना चाहिये?

यदि त्रुटि अस्वीकार्य है, तो आप अनुरोधित पृष्ठ पर जारी रखने के बजाय उन्हें त्रुटि पृष्ठ पर पुनर्निर्देशित करना चाहते हैं । यह निम्नलिखित के रूप में सरल है:

throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);

Exceptionएक ऐसा वर्ग है जो दो मापदंडों, एक संदेश और एक कोड लेता है। यदि वे आपके परिदृश्य में फिट होते हैं, तो HTTP प्रतिसाद कोड का उपयोग करने का प्रयास करने की अनुशंसा की जाती है।

यदि त्रुटि पुनर्प्राप्त करने योग्य है, तो आप संभवत: एक संदेश को अंतिम उपयोगकर्ता को वापस प्रदर्शित करना चाहते हैं, जबकि अभी भी वह पृष्ठ दिखा रहा है जो उन्होंने अनुरोध किया था। आम तौर पर इसका मतलब है कि आपको आवेदन के लिए एक संदेश 'एनकेयू' करना चाहिए:

JFactory::getApplication()->enqueueMessage($error, 'error');

enqueueMessageदो पैरामीटर, त्रुटि संदेश और एक संदेश प्रकार लेता है। अधिक जानकारी यहाँ (नीचे)।


एक तीसरी स्थिति भी है जो कम से कम मेरे लिए अक्सर होती है। जूमला विभिन्न त्रुटियों (जैसे डेटाबेस क्वेरी त्रुटि) के लिए अपवाद फेंक देगा। इसका मतलब है कि जूमला को लगता है कि यह त्रुटि अप्राप्य है। हालाँकि, आप वैसे भी जारी रखना चाह सकते हैं। (उदाहरण के लिए, यदि मैं अपने एक्सटेंशन के अपडेट पर एक तालिका बदल रहा हूं, तो मैं केवल ALTERक्वेरी चला सकता हूं , जो कि अपवाद को फेंक देगा यदि तालिका पहले बदल दी गई है।)

उस स्थिति में, आप उस कोड को लपेटना चाहते हैं जो एक प्रयास में एक अपवाद फेंक सकता है ... पकड़ अनुभाग:

try {
    // exception generating code
    throw new Exception('Normally you would have other code that calls a class that throws the exception', 500);
} catch (Exception $e) {
    $msg = $e->getMessage(); // Returns "Normally you would have other code...
    $code = $e->getCode(); // Returns '500';
    JFactory::getApplication()->enqueueMessage($msg, 'error'); // commonly to still display that error
}

ध्यान दें कि आप जो कर रहे हैं, वह अपरिवर्तनीय त्रुटि को "पकड़" रहा है और सिस्टम को पुनर्प्राप्त करने के लिए मजबूर कर रहा है और अनुरोधित पृष्ठ दिखा रहा है।


यह सब जोड़ें और आपका मामला एक अपरिवर्तनीय त्रुटि होनी चाहिए। (मुझे यह पता है क्योंकि आपके पास बाद में 'गलत रिटर्न' है, इसलिए आप संभवतः जारी रखने की योजना नहीं बनाते हैं और फ़ंक्शन को छोड़ रहे हैं।)

इस प्रकार मैं इसे इस प्रकार फिर से लिखूंगा:

// Check for errors.
if (count($errors = $this->get('Errors')))
{
    throw new Exception(implode("\n", $errors), 500);
    return false; // you can remove this too, technically since the exception will take you out of this function.
}

अच्छा उत्तर! लेकिन मैं इस पर भरोसा नहीं करूंगा $this->get('Errors')क्योंकि यह भी पदावनत है।
दिमित्री रीकुन

विफल दावे पर कोई टिप्पणी, अर्थात, आंतरिक त्रुटियां? मैं एक असफल दावे पर तुरंत मरने का कार्यक्रम चाहूंगा - क्या ऐसा करने के लिए जूमला-विशिष्ट तरीका है? फिलहाल मैं एक जोरदार हैंडलर को पंजीकृत करता हूं अगर JDEBUGवह है true
ओलले हर्स्टेड्ट ऑक्ट

12

यहां बताया गया है कि मैं त्रुटियों का प्रबंधन कैसे कर रहा हूं।

देखें या नियंत्रक

try
{
    $this->item = $this->get('Item');
}
catch (Exception $e)
{
    if ($e->getCode() == 404)
    {
        // Not found
        throw new Exception($e->getMessage(), 404);
    }

    // Generic errors
    JFactory::getApplication()->enqueueMessage(JText::_('COM_MYCOMP_ERROR_OCCURRED'), 'error');
}

इसलिए अगर मुझे अपने मॉडल से 404 कोड मिलता है (उदाहरण के लिए):

if (empty($data))
{
    throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);
}

फिर मैं इसे व्यू या कंट्रोलर में पकड़ता हूं और एक और एक्ससेप्शन फेंकता हूं, जिसे जूमला हैंडल करेगा और 404 पेज प्रदर्शित करेगा। किसी अन्य के लिए मैं केवल उपयोगकर्ता को कुछ सामान्य त्रुटि संदेश दिखाता हूं।

त्रुटियों से निपटने के बारे में इस दिलचस्प चर्चा को भी पढ़ें


4

इस तरह के अधिकांश कोड ब्लॉक को केवल enqueueMessageइसलिए बदला जा सकता है क्योंकि वे वास्तव में त्रुटि पर काम नहीं कर रहे हैं और बस JErrorउन्हें प्रिंट करने के लिए उपयोग कर रहे हैं।

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.