2010-03-10 12 views
44

catch(Exception) लगभग हमेशा एक बुरा विचार क्यों है?कैच (अपवाद) लगभग हमेशा एक बुरा विचार क्यों है?

+10

अच्छा है कि आपने * लगभग * अंदर रखा है। मैं कल्पना नहीं कर सकता कि वैश्विक त्रुटि प्रबंधन में ऐसा न करें। – Trick

+0

http://stackoverflow.com/questions/114658/catching-base-exception-class-in-net –

उत्तर

47

क्योंकि जब आप अपवाद पकड़ते हैं तो आपको इसे ठीक से संभालना होगा। और आप अपने कोड में सभी प्रकार के अपवादों को संभालने की उम्मीद नहीं कर सकते हैं। साथ ही जब आप सभी अपवादों को पकड़ते हैं, तो आपको एक ऐसा अपवाद मिल सकता है जो इसे ठीक से संभालने के लिए ढेर में ऊपरी कोड से निपटने और रोक नहीं सकता है।

सामान्य प्रिंसिपल सबसे विशिष्ट प्रकार को पकड़ने के लिए है।

+9

के संभावित डुप्लिकेट उदाहरण के लिए एक java.lang.InterruptedException तब उठाया जाता है जब थ्रेड को रोकने के लिए कहा जाता है। यदि पकड़ा और अनदेखा किया जाता है, तो थ्रेड प्रसंस्करण को बंद नहीं किया जा सकता है और आपका कोड वर्कर थ्रेड में चलाने के लिए अनुचित हो जाता है। यह एक उदाहरण है, अन्य हो सकते हैं। – Pierre

+1

मैं लोगों के उनके ढांचे को समझने का एक बड़ा प्रशंसक हूं। इस सलाह का प्राथमिक कारण भयानक है, 9 0% समय, कोड लोग अपवाद हैंडलिंग लिख रहे हैं, उनके एपीआई की सीमा पर है। मैं मानता हूं कि एक एपीआई के भीतर, आपको हमेशा उचित अपवादों को पकड़ना चाहिए, लेकिन जब आप एपीआई सीमा पर हों, तो कृपया सिस्टम को मारने वाली हर चीज़ को पकड़ें। – coding

5

क्योंकि आप वास्तव में नहीं जानते कि एक अपवाद क्यों हुआ, और कई अपवादों को बहुत विशेष कार को सही ढंग से संभाला जाना चाहिए (यदि संभव हो तो), जैसे आउटऑफमेमरीएक्सप्शन और इसी तरह के निम्न-स्तरीय सिस्टम अपवाद।

इसलिए, आप केवल पकड़ने चाहिए अपवाद:

  • जो कि वास्तव में आप जानते हैं कि इसके साथ सौदा करने के लिए कैसे (जैसे FileNotFoundException या तो)
  • जब आप उन्हें बाद में फिर से उठाना (उदाहरण के पद प्रदर्शन करने के लिए -fail सफाई)
  • जब आप किसी अन्य धागा
+0

OutOfMemoryException जैसी कोई चीज़ नहीं है। OutOfMemoryError है जो थ्रोबल पदानुक्रम के तहत है। –

+2

@EladTabak, आप निश्चित रूप से जावा के संबंध में सही हैं। ऐसा कहा जा रहा है कि जब मैंने प्रश्न का उत्तर दिया (देखें [संशोधन इतिहास] (http://stackoverflow.com/posts/2416316/revisions)), और व्यक्त अर्थ अभी भी सही है - परवाह किए बिना टैग "जावा" नहीं था वास्तविक वातावरण – Lucero

5

यह तुम क्या जरूरत पर निर्भर करता है के लिए अपवाद के परिवहन के लिए की जरूरत है। यदि आपको विभिन्न तरीकों से विभिन्न प्रकार के अपवादों को संभालने की आवश्यकता है तो आपको एकाधिक पकड़ ब्लॉक का उपयोग करना चाहिए और जितना संभव हो उतना विशिष्ट अपवाद पकड़ना चाहिए।

लेकिन कभी-कभी आपको सभी अपवादों को उसी तरह से संभालने की आवश्यकता हो सकती है। ऐसे मामलों में पकड़ (अपवाद) ठीक हो सकता है। उदाहरण के लिए:

try 
    { 
     DoSomething(); 
    } 
    catch (Exception e) 
    { 
     LogError(e); 
     ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user. 
    } 
+2

यह पालन करने के लिए एक अच्छा पैटर्न नहीं है; लॉगिंग इस तरह नहीं की जानी चाहिए क्योंकि आपको कोशिश करने के प्रत्येक "स्तर" के लिए एक ही प्रविष्टियों का एक गुच्छा मिलेगा। – Lucero

+0

मैं सहमत हूं, मैंने इसे उदाहरण के रूप में उपयोग किया है। सबसे अच्छा उदाहरण नहीं हो सकता है :) –

+1

@ लुसेरो: मुझे लगता है कि एक लॉगिंग फ्रेमवर्क होना बेहतर होगा जो अनावश्यक प्रविष्टियों को समेकित कर सकता है, मान लीजिए कि जो भी परत हैंडल (निगल) अपवाद इसे लॉग करेगी। इसके अलावा, जब तक कि अपवाद इतने असंख्य न हों कि उन्हें कई बार लॉग इन करना एक प्रदर्शन बाधा उत्पन्न करेगा (जिस स्थिति में मैं कहूंगा * यह एक समस्या है जिसे फिक्सिंग की आवश्यकता है) मुझे लगता है कि लॉग में अनावश्यक जानकारी है, जिसे बाद में फ़िल्टर किया जा सकता है एक लॉग देखने की उपयोगिता, एक संक्षिप्त संक्षिप्त लॉग रखने के लिए बेहतर होगा जिसमें जानकारी के एक टुकड़े की कमी होती है जो एक को समाप्त करने की आवश्यकता होती है। – supercat

8

यदि आप उन्हें सही तरीके से संभाल सकते हैं तो आपको केवल अपवादों को पकड़ना चाहिए। चूंकि आप सभी संभावित अपवादों को सही ढंग से संभाल नहीं सकते हैं, आपको उन्हें पकड़ना नहीं चाहिए :-)

+8

ऐसी सोच के साथ एक बड़ी समस्या यह है कि ऐसी कई स्थितियां हैं जिनमें 99% अपवादों को फेंक दिया जा सकता है, यह रिपोर्ट करना होगा कि कुछ कार्यवाही पूरी नहीं हो सकती है और जीवन के साथ मिलती है, लेकिन प्रत्येक एकल की पहचान करना अपवाद का प्रकार जिसके लिए कार्रवाई का उचित तरीका मुश्किल होगा यदि असंभव नहीं है। बहुत बुरा है "सीपीयू आग पर है" अपवादों से "अनुरोध को पूरा नहीं कर सका" अपवाद के लिए कोई तंत्र नहीं है। – supercat

+1

सीपीयू आग लग रहा है शायद कुछ प्रकार के 'java.lang.Error' का कारण बन जाएगा। – yegeniy

+0

> एक त्रुटि थ्रोबल का उप-वर्ग है जो गंभीर समस्याओं को इंगित करता है कि एक उचित अनुप्रयोग को पकड़ने की कोशिश नहीं करनी चाहिए। – yegeniy

15

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

कभी-कभी आप तरीकों कि जांचे हुए अपवादों फेंक कॉल करने के लिए की आवश्यकता होगी:

+0

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

+0

@ user316117 'अपवाद' जावा में सभी अपवादों का शीर्ष वर्ग है। पकड़ने का मतलब है कि आप सभी संभावित त्रुटियों को पकड़ते हैं। आपको कैसे पता चलेगा कि इस तरह के ब्लॉक में क्या करना है? यदि आप किसी निश्चित त्रुटि पर प्रतिक्रिया देना चाहते हैं, तो इसके विशिष्ट अपवाद को पकड़ें और इसके साथ काम करें। आपकी आंखों को अंधा करने के अलावा सभी संभावित अपवादों को पकड़ने के लिए कोई व्यावहारिक उपयोग नहीं है (और मैंने देखा है कि बहुत से सहकर्मियों ने ऐसा किया क्योंकि वे कार्यदिवस के अंत में घर जाना चाहते हैं)। – dimitarvp

+0

@dimitarvp थ्रोबल सभी अपवादों का शीर्ष वर्ग है। इसमें दो उप-वर्ग हैं जो विभाजन दो शाखाओं में अपवाद हैं। उनमें से एक अपवाद है और दूसरा त्रुटि है। –

0

यह जावा विशिष्ट हो सकता है। यदि यह आपके ईजेबी/बिजनेस लॉजिक लेयर में है तो आपके पास 2 विकल्प हैं - उन्हें पकड़ें या उन्हें फिर से फेंक दें।

विशिष्ट अपवाद वर्गों को पकड़ने का अर्थ है कि आपको अपने कार्यों का पुन: विश्लेषण करने की आवश्यकता होगी जिसके लिए आप यह देखने के लिए अपवादों को फेंक सकते हैं कि यह कोड अपवादों को कैसे संभालता है। आप अक्सर "क्या होगा ..." स्थिति में आ जाएंगे और अपवादों को सही तरीके से संभाले जाने पर यह बहुत ही प्रयास हो सकता है।

पुन: फेंकने का मतलब है कि आपके ईजेबी को कॉल करने वाले कोड को पकड़ने वाले कोड से भंग कर दिया जाएगा जो आमतौर पर कॉलिंग क्लास के लिए कुछ भी नहीं होगा। N.B. ईजेबी विधियों से चेक अपवादों को फेंकने का मतलब यह होगा कि आप किसी लेनदेन को मैन्युअल रूप से रोल करने के लिए ज़िम्मेदार हैं।

0

क्या अभी तक @anthares द्वारा उत्तर दिया इसके अलावा:

जब आप अपवाद को पकड़ने आप इसे ठीक से संभाल करने वाला रहे हैं क्योंकि। और आप अपने कोड में सभी प्रकार के अपवादों को संभालने की उम्मीद नहीं कर सकते हैं। साथ ही जब आप सभी अपवादों को पकड़ते हैं, तो आपको एक ऐसा अपवाद मिल सकता है जो इसे ठीक से संभालने के लिए ढेर में ऊपरी कोड से निपटने और रोक नहीं सकता है।

सामान्य प्रिंसिपल सबसे विशिष्ट प्रकार को पकड़ने के लिए है।

catch(Exception) एक खराब अभ्यास है क्योंकि यह सभी रनटाइम अपवाद (अनचेक अपवाद) को भी पकड़ता है।

0

लेकिन कभी-कभी यह ठीक है! जैसे कि आपके पास कोड का एक टुकड़ा है जो कुछ 'अतिरिक्त' करता है, जिसे आप वास्तव में परवाह नहीं करते हैं, और आप नहीं चाहते हैं कि यह आपके आवेदन को उड़ाए। उदाहरण के लिए, मैंने हाल ही में एक बड़े आवेदन पर काम किया जहां हमारे व्यापार भागीदारों ने एक नई लॉग फ़ाइल में एक निश्चित दैनिक लेनदेन सारांशित किया था। उन्होंने समझाया कि लॉग उन सभी के लिए महत्वपूर्ण नहीं था, और यह एक आवश्यकता के रूप में योग्य नहीं था। यह कुछ अतिरिक्त था जो उन्हें संसाधित किए जाने वाले डेटा को समझने में मदद करेगा। उन्हें इसकी आवश्यकता नहीं थी, क्योंकि वे कहीं और जानकारी प्राप्त कर सकते थे। तो यह एक दुर्लभ मामला है जहां अपवादों को पकड़ने और निगलने के लिए यह बिल्कुल ठीक है।

मैंने एक ऐसी कंपनी में भी काम किया जहां सभी थ्रोबेल पकड़े गए, और फिर एक कस्टम रनटाइम अपवाद के अंदर पुनर्स्थापित किया गया। मैं इस दृष्टिकोण की सिफारिश नहीं करता, लेकिन सिर्फ यह बताता हूं कि यह किया गया है।

0

मुझे कैच (अपवाद) के दो स्वीकार्य उपयोग मिलते हैं: - एप्लिकेशन के शीर्ष स्तर पर (उपयोगकर्ता को लौटने से पहले)। इस तरह आप एक पर्याप्त संदेश प्रदान कर सकते हैं। - किसी व्यवसाय के लिए निम्न-स्तर के अपवादों को मास्क करने के लिए इसका उपयोग करना।

पहला मामला आत्म explanative है, लेकिन मुझे दूसरे का विकास करते हैं:

कर:

try { 
    xxxx 
} catch(Exception e) { 
    logger.error("Error XXX",e) 
} 

बग मास्किंग @dimitarvp की तरह कहा है।

लेकिन

try { 
    xxxx 
} catch(Exception e) { 
    throw new BussinessException("Error doing operation XXX",e) 
} 

यह एक अलग बात है। इस तरह आप कालीनों के नीचे कीड़े को छिपाने और छुपा नहीं रहे हैं। आप उच्च अनुप्रयोग परतों के लिए एक और व्याख्यात्मक संदेश के साथ एक उच्च स्तरीय अपवाद प्रदान कर रहे हैं।

यह हमेशा भी महत्वपूर्ण है कि दो सही परत पर अपवाद का प्रबंधन करें। यदि आप एक उच्च व्यापार परत के लिए निम्न स्तर के अपवाद को आगे बढ़ने देते हैं तो यह व्यावहारिक रूप से असंभव है कि उच्च परत इसे अच्छी तरह से प्रबंधित कर सकती है। उन मामलों में, मैं एक ऐसे व्यवसाय के साथ निम्न स्तर के अपवादों को मास्क करना पसंद करता हूं जो बेहतर संदर्भ और संदेश प्रदान करता है और इसमें विवरणों पर जाने में भी मूल अपवाद है।

फिर भी, यदि आप अधिक ठोस अपवादों को पकड़ सकते हैं और आप उनके लिए बेहतर उपचार प्रदान कर सकते हैं तो आपको यह करना होगा।

यदि कोड के ब्लॉक में आप एक एसक्यूलेक्सप्शन और नेटवर्क अपवाद प्राप्त कर सकते हैं तो आपको उन्हें पकड़ना होगा और उनमें से प्रत्येक के लिए पर्याप्त संदेश और उपचार प्रदान करना होगा। लेकिन यदि कोशिश/पकड़ ब्लॉक के अंत में आपके पास एक अपवाद है जो इसे BussinessException के साथ मैपिंग करता है, यह मेरे लिए ठीक है। वास्तव में, मुझे पर्याप्त लगता है कि उच्च सेवा परतें केवल व्यावसायिक अपवाद (अंदर के विवरण के साथ) फेंकती हैं।

संबंधित मुद्दे