क्या नेस्टेड ट्रायल / कैच एक बुरे विचार को रोकते हैं?


83

मान लीजिए कि हमारे पास एक संरचना है जैसे:

Try
  ' Outer try code, that can fail with more generic conditions, 
  ' that I know less about and might not be able to handle

  Try
    ' Inner try code, that can fail with more specific conditions,
    ' that I probably know more about, and are likely to handle appropriately
  Catch innerEx as Exception
    ' Handle the inner exception
  End Try

Catch outerEx as Exception
  ' Handle outer exception
End Try

मैंने कुछ राय देखी है कि Tryइस तरह के घोंसले के शिकार को हतोत्साहित किया जाता है, लेकिन मुझे कोई विशेष कारण नहीं मिला।

क्या यह बुरा कोड है? यदि हां, तो क्यों?


2
यह सुनिश्चित नहीं है कि स्निपेट वास्तव में कितना सही है। लेकिन एक्सेप्ट को पकड़ने पर वास्तव में आपको पता नहीं है कि एक हेकॉफ़लॉट है। यह कुछ भी हो सकता है । जब VB.NET समर्थन करता है कि क्लॉज का लाभ उठाने पर विचार करें।
हंस पैसेंट

जवाबों:


86

ऐसी कुछ परिस्थितियाँ हैं जहाँ वे एक अच्छा विचार हैं, जैसे एक पूरी विधि के लिए एक प्रयास / पकड़ और दूसरा एक लूप के अंदर जैसा कि आप अपवाद को संभालना चाहते हैं और शेष संग्रह को संसाधित करना जारी रखते हैं।

वास्तव में ऐसा करने का एकमात्र कारण यह है कि यदि आप उस बिट को छोड़ना चाहते हैं जो कि गलत है और उस पर चलना है, तो स्टैक को खो देने और संदर्भ खोने के बजाय। एक संपादक में कई फाइलें खोलना एक उदाहरण है।

उस ने कहा, अपवाद (जैसा कि नाम का अर्थ है) असाधारण होना चाहिए। एक कार्यक्रम उन्हें संभालना चाहिए लेकिन सामान्य निष्पादन प्रवाह के हिस्से के रूप में उनसे बचने की कोशिश करें। वे अधिकांश भाषाओं में कम्प्यूटेशनल रूप से महंगे हैं (पायथन एक उल्लेखनीय अपवाद है)।

एक अन्य तकनीक जो उपयोगी हो सकती है वह विशिष्ट अपवाद प्रकारों को पकड़ रही है ...

Try
    'Some code to read from a file

Catch ex as IOException
    'Handle file access issues (possibly silently depending on usage)
Catch ex as Exception
    ' Handle all other exceptions.
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate
    Throw
End Try

हम भी अपनी गलती से निपटने की दिनचर्या में नेस्टेड कोशिश / कैच का उपयोग करते हैं ...

    Try
        Dim Message = String.Format("...", )
        Try
            'Log to database
        Catch ex As Exception
            'Do nothing
        End Try

        Try
            'Log to file
        Catch ex As Exception
            'Do nothing
        End Try
    Catch ex As Exception
        'Give up and go home
    End Try

7
बैकग्राउंड थ्रेड में लॉग इन करना एक जगह है जहां मैं एक आंतरिक कोशिश / कैच का उपयोग करूंगा। मैं इस पद्धति को समाप्त नहीं करना चाहता क्योंकि यह दस्तावेज नहीं कर सकती थी कि यह क्या कर रही है।
गूच

@ सच, ​​मैं भी ऐसा करता हूं, मैं इसे अपने जवाब में जोड़ूंगा।
बेसिक

37

मुझे नहीं लगता कि नेस्टेड Try/ Catchब्लॉक्स के बारे में कुछ भी गलत है , सिवाय इसके कि उन्हें नेविगेट करना मुश्किल हो सकता है और इस बात की संभावना है कि आप कुछ रिफैक्टरिंग (आंतरिक Try/ Catchअपने तरीके से, उदाहरण के लिए) कर सकते हैं।

लेकिन मैं इस टिप्पणी को संबोधित करना चाहता हूं:

' Outer try code, that can fail with more generic conditions, 
' that I know less about and might not be able to handle

यदि आप यह नहीं जानते कि किसी विशेष स्थिति में अपवादों को कैसे संभालना है, तो मुझ पर विश्वास करें: उन्हें पकड़ें। अपने ऐप को क्रैश होने देने के लिए बेहतर है (मेरा मतलब है, आप जानते हैं, इसे लॉग इन करें ; बस इसे निगल न करें) कुछ ऐसी चीज़ों को पकड़ने के लिए जिन्हें आप नहीं जानते कि इससे कैसे उबरें और फिर अपने ऐप को दूषित स्थिति में अपने रास्ते पर जारी रखने दें। । उस बिंदु से व्यवहार सबसे अच्छा अप्रत्याशित होगा।


यह सच है। बाहरी अपवाद को पकड़ने के बिंदु पर मैं जारी नहीं रखना चाहूंगा। मैं शटडाउन को अच्छी तरह से बंद / पुनः आरंभ करने में सक्षम होने के बारे में अधिक सोच रहा था, और उपयोगकर्ता को "बदसूरत दुर्घटना" के साथ झटका नहीं देता
गोरो

10
@ गोरो: उस मामले में, मैं Application.UnhandledExceptionप्रति-विधि Try/ Catchब्लॉक के बजाय एक ऐप-वाइड अपवाद हैंडलिंग तंत्र (जैसे, अगर यह WinForms है, तो घटना को संभालना ) की सिफारिश करेगा।
दान ताओ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.