अपवाद कब फेंकना है?


435

मेरे पास हर शर्त के लिए अपवाद हैं जो मेरे आवेदन की अपेक्षा नहीं करते हैं। UserNameNotValidException, PasswordNotCorrectExceptionआदि।

हालांकि मुझे बताया गया था कि मुझे उन परिस्थितियों के लिए अपवाद नहीं बनाना चाहिए। मेरे यूएमएल में वे मुख्य प्रवाह के अपवाद हैं, तो यह अपवाद क्यों नहीं होना चाहिए?

अपवाद बनाने के लिए कोई मार्गदर्शन या सर्वोत्तम अभ्यास?


58
कृपया पुनः खोलें, यह एक बहुत ही समझदार और मान्य प्रश्न है। किसी भी प्रश्न में एक निश्चित मात्रा में राय शामिल होती है, लेकिन इस मामले में मुझे संदेह है कि यह 'सर्वोत्तम अभ्यास' का मामला है।
टिम लॉन्ग

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

12
मैं यह भी मानता हूं कि इस प्रश्न को फिर से खोला जाना चाहिए क्योंकि यह सर्वोत्तम प्रथाओं से संबंधित है। वैसे सर्वश्रेष्ठ अभ्यास हमेशा राय होते हैं जो दूसरों की मदद कर सकते हैं।
अजय शर्मा

6
Microsoft कहता है: "त्रुटि कोड वापस न करें। अपवाद फ्रेमवर्क में त्रुटियों की रिपोर्ट करने का प्राथमिक साधन है।" और "... यदि कोई सदस्य सफलतापूर्वक ऐसा नहीं कर सकता है जिसे वह करने के लिए डिज़ाइन किया गया है, तो उसे निष्पादन विफलता माना जाना चाहिए और अपवाद को फेंक दिया जाना चाहिए।" msdn.microsoft.com/library/ms229030%28v=vs.100%29.aspx
Matsen75

4
ये पूरी तरह से समझदार अपवाद हो सकते हैं, यह सिर्फ इस बात पर निर्भर करता है कि कौन से तरीके उन्हें फेंकते हैं। IsCredentialsValid(username,password)यदि उपयोगकर्ता नाम या पासवर्ड अमान्य है, तो एक विधि को अपवाद नहीं कहा जाना चाहिए, लेकिन गलत है। लेकिन कहते हैं कि एक विधि जो डेटाबेस से डेटा पढ़ती है वह वैध रूप से इस तरह के अपवाद को फेंक सकती है, अगर प्रमाणीकरण विफल हो जाता है। संक्षेप में: आपको एक अपवाद को फेंकना चाहिए यदि कोई विधि उस कार्य को करने में सक्षम नहीं है जिसे वह करने वाला है।
जैक्सबी

जवाबों:


629

मेरी व्यक्तिगत दिशानिर्देश है: एक अपवाद तब फेंका जाता है जब वर्तमान कोड ब्लॉक की एक मौलिक धारणा झूठी पाई जाती है।

उदाहरण 1: कहते हैं कि मेरे पास एक फ़ंक्शन है जो एक मनमाना वर्ग की जांच करने वाला है और अगर यह वर्ग सूची <> से विरासत में मिला है तो वापस लौटना चाहिए। यह फ़ंक्शन प्रश्न पूछता है, "क्या यह वस्तु सूची का वंशज है?" इस फ़ंक्शन को कभी भी अपवाद नहीं फेंकना चाहिए, क्योंकि इसके संचालन में कोई ग्रे क्षेत्र नहीं हैं - हर एक वर्ग या तो सूची से <या> वारिस नहीं करता है, इसलिए उत्तर हमेशा "हाँ" या "नहीं" है।

उदाहरण 2: कहते हैं कि मेरे पास एक और फ़ंक्शन है जो सूची <> की जांच करता है और अगर इसकी लंबाई 50 से अधिक है, और लंबाई कम है तो गलत है। यह फ़ंक्शन सवाल पूछता है, "क्या इस सूची में 50 से अधिक आइटम हैं?" लेकिन यह सवाल एक धारणा बनाता है - यह मानता है कि जो वस्तु दी गई है वह एक सूची है। अगर मैं इसे NULL को सौंपता हूं, तो यह धारणा झूठी है। उस मामले में, अगर समारोह रिटर्न या तो सही या गलत है, तो यह अपने आप नियमों को तोड़ने है। फ़ंक्शन कुछ भी नहीं लौटा सकता है और यह दावा करता है कि उसने प्रश्न का सही उत्तर दिया है। तो यह वापस नहीं आता है - यह एक अपवाद फेंकता है।

यह "लोड किए गए प्रश्न" तार्किक गिरावट के बराबर है। हर फंक्शन एक सवाल पूछता है। यदि यह दिया गया इनपुट उस प्रश्न को एक गिरावट बनाता है, तो एक अपवाद फेंक दें। यह रेखा उन कार्यों के साथ खींचना कठिन है जो शून्य लौटाते हैं, लेकिन नीचे की रेखा है: यदि फ़ंक्शन के इनपुट के बारे में मान्यताओं का उल्लंघन किया जाता है, तो इसे सामान्य रूप से वापस जाने के बजाय एक अपवाद फेंक देना चाहिए।

इस समीकरण का दूसरा पक्ष है: यदि आप अपने कार्यों को अक्सर अपवाद फेंकते हुए पाते हैं, तो आपको शायद उनकी मान्यताओं को परिष्कृत करने की आवश्यकता है।


15
बिल्कुल सही! एक अपवाद तब ही फेंका जाता है जब केवल फ़ंक्शन प्रींडॉन्डिशन (तर्कों के बारे में मान्यताओं) को तोड़ दिया जाता है !
लाइटमैन

11
भाषा विज्ञान में इसे कभी-कभी पूर्वसर्ग विफलता कहा जाता है । क्लासिक उदाहरण बर्ट्रेंड रसेल के कारण है: "फ्रांस का राजा गंजा है" इसका जवाब हां या नहीं दिया जा सकता है, (सम्मान। "फ्रांस का राजा गंजा है" न तो सच है और न ही गलत है), क्योंकि इसमें एक गलत अनुमान है। , अर्थात् फ्रांस का एक राजा है। प्रायोजन विफलता अक्सर निश्चित विवरण के साथ देखी जाती है, और यह प्रोग्रामिंग करते समय सामान्य है। उदाहरण के लिए "किसी सूची के प्रमुख" के पास कोई सूची खाली होने पर पूर्वनिर्धारण विफलता है, और फिर अपवाद को फेंकना उचित है।
मोहन

यह संभवतः सबसे अच्छा स्पष्टीकरण है!
गौरव

धन्यवाद। इसलिए। बहुत। "फ्रांस का राजा गंजा है"। मैंने इससे पहले सुना है जब मेइन्गॉन्ग के जंगल पर शोध किया गया .... :) धन्यवाद। @ मोहान
एर्लिचबचमैन

285

क्योंकि वे चीजें हैं जो सामान्य रूप से होंगी। अपवाद नियंत्रण प्रवाह तंत्र नहीं हैं। उपयोगकर्ताओं को अक्सर पासवर्ड गलत मिलते हैं, यह एक असाधारण मामला नहीं है। अपवाद वास्तव में दुर्लभ वस्तु होनी चाहिए,UserHasDiedAtKeyboard प्रकार की परिस्थितियां।


3
हम्म, नहीं। अपवादों को नियंत्रण प्रवाह तंत्र के रूप में उपयोग किया जा सकता है यदि अधिकतम प्रदर्शन की आवश्यकता नहीं है, जो कि अधिकांश वेब-ऐप्स के लिए सही है। पायथन अपवादों को समाप्त करने के लिए अपवाद 'स्टॉपइंटरेशन' का उपयोग करता है, और यह बहुत अच्छी तरह से काम करता है। लागत IO, आदि की तुलना में कुछ भी नहीं है
Seun Osewa

9
+1 उत्कृष्ट उत्तर। मैं एपीआई पर काम करने वाले डेवलपर्स से इतना निराश हूं कि मुझे हर छोटी चीज़ के लिए अपवादों का उपभोग करना पड़ता है। बहुत कम मामलों में वास्तव में अपवादों की आवश्यकता होती है। यदि आपके पास 25 अलग-अलग प्रकार के अपवाद हैं, तो अपने डिज़ाइन पर फिर से नज़र डालें, आप गलत कर रहे होंगे।
7wp

1
क्या कोई अपवाद होना चाहिए जब उपयोगकर्ता एक गैरकानूनी कार्रवाई की कोशिश करता है जिसे वह वेबपेज कोड में हेरफेर करने की अनुमति नहीं देता है, उदाहरण के लिए जैसे स्टैकऑवरफ़्लो में किसी और के पदों को यहां से हटाना?
रजत गुप्ता

30
अपवाद नियंत्रण प्रवाह तंत्र हैं। आप उन्हें फेंक सकते हैं। आप उन्हें पकड़ सकते हैं। आपने नियंत्रण को किसी अन्य कोड कोड में स्थानांतरित कर दिया। यह नियंत्रण प्रवाह है। एकमात्र कारण भाषाओं में अपवाद हैं, इसलिए आप यह पूछे बिना सीधा कोड लिख सकते हैं कि "क्या यह बात अभी असफल हुई?" सब कुछ करने के बाद। हास्केल, उदाहरण के लिए, अपवाद नहीं हैं क्योंकि मोनाड्स और डू-नोटेशन आपके लिए त्रुटि जांच को स्वचालित कर सकते हैं।
जेसी

2
अपवाद नियंत्रण प्रवाह तंत्र से अधिक हैं। वे असाधारण परिणामों के बारे में ग्राहक को उपयोगी जानकारी (विधि) देते हैं, जिसके बारे में उन्हें जानकारी होनी चाहिए । यही है, ठीक से उपयोग किया जाता है, अपवाद API को और अधिक मजबूत बनाते हैं
इडेलवैल

67

मेरे छोटे दिशानिर्देश महान पुस्तक "कोड पूरा" से बहुत प्रभावित हैं:

  • उन चीजों के बारे में सूचित करने के लिए अपवादों का उपयोग करें जिन्हें अनदेखा नहीं किया जाना चाहिए।
  • यदि त्रुटि स्थानीय रूप से नियंत्रित की जा सकती है तो अपवादों का उपयोग न करें
  • सुनिश्चित करें कि अपवाद आपकी दिनचर्या के बाकी हिस्सों के समान स्तर पर हैं।
  • अपवाद वास्तव में असाधारण है के लिए आरक्षित होना चाहिए ।

35

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

संपादित करें: मुझे अपवादों का उपयोग करना पसंद नहीं है क्योंकि आप यह नहीं बता सकते हैं कि क्या कोई विधि केवल कॉल को देखकर एक अपवाद को फेंक देती है। यही कारण है कि अपवादों का उपयोग केवल तभी किया जाना चाहिए यदि आप स्थिति को सभ्य तरीके से नहीं संभाल सकते हैं (सोचें "स्मृति से बाहर" या "कंप्यूटर में आग लगी है")।


"मुझे अपवादों का उपयोग करना पसंद नहीं है क्योंकि आप यह नहीं बता सकते हैं कि क्या कोई विधि केवल कॉल को देखकर एक अपवाद को फेंकती है।" यही कारण है कि भाषाओं के लिए जाँच अपवाद हैं जो उनका समर्थन करते हैं।
न्यूटॉपियन

1
जाँच किए गए अपवादों में समस्याओं का अपना सेट है। मैं अभी भी "असाधारण परिस्थितियों" के अपवादों का उपयोग करता हूं, उन चीजों के लिए नहीं जो सामान्य वर्कफ़्लो का हिस्सा हैं।
एरिकशोफर

2
आपके संपादन के जवाब में। मैं हमेशा अपने xml डॉक्स में सारांश खंड के अंत में डाल देता हूं, जो फ़ंक्शन को फेंकता है ताकि मैं उस जानकारी को अंतर्मुखता में देख सकूं।
मैथ्यू वाइन

1
क्या कोई अपवाद होना चाहिए जब उपयोगकर्ता एक गैरकानूनी कार्रवाई की कोशिश करता है जिसे वह वेबपेज कोड में हेरफेर करने की अनुमति नहीं देता है, उदाहरण के लिए जैसे स्टैकऑवरफ़्लो में किसी और के पदों को यहां से हटाना?
रजत गुप्ता

1
ऐसा लगता है कि आप त्रुटियों को संभालने के बारे में बात कर रहे हैं (हमारी मेमोरी, कंप्यूटर पर आग) बनाम हैंडलिंग कोड अपवाद (गुम रिकॉर्ड, अमान्य इनपुट प्रकार, आदि)। मुझे लगता है कि दोनों के बीच एक अलग अंतर है।
चक बर्गेस

28

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


6
आपको अपवाद पर प्रोग्राम निष्पादन को रोकने की आवश्यकता नहीं है ... अपवाद को फेंक दें, कॉल करने वाला तब छूट को पकड़ता है और यदि संभव हो, तो लॉग इन करें और त्रुटि करें और आगे बढ़ें। कॉल स्टैक तक अपवादों को फेंकने के लिए यह 'खराब रूप' है - इसे
पकड़ें

2
लेकिन अगर आप सीधे इसे संभाल सकते हैं, तो उन्हें भी क्यों फेंकें। यदि पासवर्ड गलत है या कुछ भी गलत है, तो मैं बस एक गलत रिटर्न देता हूं और एक त्रुटि देता
हूं

" डिस्क पर फ़ाइल गुम " अधिकांश भाषा चौखटे, उदाहरण के लिए .NET फ्रेमवर्क, फ़ाइल अस्तित्व के लिए भी जाँच करने के लिए एपीआई प्रदान करता है। सीधे फ़ाइल तक पहुंचने से पहले उनका उपयोग क्यों नहीं किया जाता है!
user1451111

23

दूसरों का प्रस्ताव है कि अपवादों का उपयोग नहीं किया जाना चाहिए क्योंकि खराब लॉगिन सामान्य प्रवाह में अपेक्षित है यदि उपयोगकर्ता गलत करता है। मैं असहमत हूं और मुझे तर्क नहीं मिला। एक फ़ाइल खोलने के साथ इसकी तुलना करें .. यदि फ़ाइल मौजूद नहीं है या किसी कारण से उपलब्ध नहीं है, तो एक अपवाद फ्रेमवर्क द्वारा फेंक दिया जाएगा। इसके ऊपर के तर्क का उपयोग करना Microsoft द्वारा एक गलती थी। उन्हें एक त्रुटि कोड वापस करना चाहिए था। पार्सिंग, वेबरेक्स्ट, इत्यादि के लिए समान।

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


सिवाय आप यह जांच कर सकते हैं कि फ़ाइल कॉल करने से पहले मौजूद है (आपके ढांचे के आधार पर)। तो वह सुविधा मौजूद है और इस प्रकार यदि फ़ाइल चेक के बीच गायब हो जाती है और आप उसे खोलने का प्रयास करते हैं तो वह अपवाद है।
ब्‍लॉडरार्ट

7
मौजूदा फ़ाइल का मतलब यह नहीं है कि उपयोगकर्ता को उदाहरण के लिए फ़ाइल पर लिखने की अनुमति है। हर संभव समस्या के लिए जाँच वास्तव में थकाऊ और त्रुटि प्रवण है। + आप कोड (DRY) की नकल कर रहे हैं।
ब्योर्न रिपेन

अमान्य पासवर्ड अपवाद के साथ एक बिंदु यह है कि रिटर्न कोड समाधान के साथ तुलना में कोई सुस्ती पासवर्ड में मानव उपयोगकर्ता टाइपिंग के लिए स्वीकार्य नहीं है।
पेपरफोर्स

7
"स्टैक अप एन स्तरों के माध्यम से रिटर्न मानों का प्रचार करके अपने कोड की शिकायत करना ऊर्जा की बर्बादी है और इसके परिणामस्वरूप गड़बड़ कोड होगा"। मेरे लिए, अपवादों का उपयोग करने का एक बहुत मजबूत कारण है। अच्छा कोड आमतौर पर छोटे कार्यों से युक्त होता है। आप उस त्रुटि कोड को एक छोटे फ़ंक्शन से दूसरे में बार-बार पारित नहीं करना चाहते हैं।
बेलुचिन

मुझे लगता है कि एक अनुमान से भ्रम की स्थिति शायद यह loginहो सकती है कि एक पूर्व-विधि का अनुमानित परिणाम यह होगा कि एक पासवर्ड गलत हो सकता है, यह वास्तव में यह निर्धारित करने के लिए उपयोग किया जा सकता है, और इस मामले में अपवाद नहीं रखना चाहेगा; एक file openप्रकार के परिदृश्य में, जिसमें एक विशेष परिणाम वांछित है- यदि सिस्टम गलत इनपुट मापदंडों या किसी बाहरी कारक के कारण परिणाम देने में असमर्थ है, तो यह एक अपवाद का पूरी तरह से तार्किक उपयोग है।
theMayer

17

अपवाद कुछ हद तक महंगा प्रभाव है, उदाहरण के लिए यदि आपके पास एक उपयोगकर्ता है जो एक अमान्य पासवर्ड प्रदान करता है, तो यह आमतौर पर विफलता ध्वज, या कुछ अन्य संकेतक को वापस करने के लिए एक बेहतर विचार है कि यह अमान्य है।

यह इस कारण से है कि अपवादों को नियंत्रित किया जाता है, सही खराब इनपुट और अद्वितीय महत्वपूर्ण स्टॉप आइटम अपवाद होने चाहिए, लेकिन लॉगिन जानकारी विफल नहीं हुई।


14

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


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

  • एक पूर्व शर्त पूरी नहीं हुई है (जो आमतौर पर निम्न में से एक को असंभव बनाता है) या
  • वैकल्पिक बाद की स्थिति को पूरा करने में विफल होगा या
  • विकल्प एक आक्रमणकारी को बनाए रखने में विफल होगा।

यह बेहतर क्यों है? क्या यह सवाल को पूर्वधारणा, पोस्टकंडिशन और इनवेरिएंट के बारे में कई सवालों के साथ प्रतिस्थापित नहीं करता है ? यह कई जुड़े कारणों के लिए बेहतर है।

  • Preconditions, postconditions और invariants हमारे कार्यक्रम (इसकी आंतरिक एपीआई) की डिजाइन विशेषताएं हैं , जबकि निर्णयthrow एक कार्यान्वयन विवरण है। यह हमें ध्यान में रखने के लिए मजबूर करता है कि हमें डिजाइन और इसके कार्यान्वयन पर अलग से विचार करना चाहिए, और एक विधि को लागू करते समय हमारा काम कुछ ऐसा उत्पादन करना है जो डिजाइन की बाधाओं को पूरा करता है।
  • यह हमें पूर्वधारणाओं, पदबंधों और आक्रमणकारियों के संदर्भ में सोचने के लिए मजबूर करता है, जो कि एकमात्र हैं धारणाएं हैं जो हमारे विधि के कॉलर को बनाना चाहिए, और हमारे कार्यक्रम के घटकों के बीच ढीली युग्मन को सक्षम करते हुए, सटीक रूप से व्यक्त की जाती हैं।
  • यह ढीला युग्मन हमें आवश्यक होने पर कार्यान्वयन को फिर से करने की अनुमति देता है।
  • पश्चात की स्थिति और अपरिवर्तनीय परीक्षण योग्य हैं; इससे कोड में परिणाम होता है जिसे आसानी से परीक्षण किया जा सकता है, क्योंकि पोस्ट-स्थितियां हमारे यूनिट-टेस्ट कोड की जांच कर सकती हैं (परख) कर सकती हैं।
  • स्वाभाविक रूप से बाद की स्थितियों के संदर्भ में सोचने से एक ऐसी स्थिति पैदा होती है, जिसमें सफलता के बाद की स्थिति होती है , जो अपवादों का उपयोग करने की स्वाभाविक शैली है। आपके प्रोग्राम का सामान्य ("खुश") निष्पादन पथ रैखिक रूप से बाहर रखा गया है, जिसमें सभी त्रुटि हैंडलिंग कोड क्लॉस में चले गए catchहैं।

10

मैं कहूंगा कि अपवाद का उपयोग करने पर कोई कठिन और तेज़ नियम नहीं हैं। हालाँकि इनका उपयोग करने या न करने के अच्छे कारण हैं:

अपवादों का उपयोग करने के कारण:

  • आम मामले के लिए कोड का प्रवाह स्पष्ट है
  • एक वस्तु के रूप में जटिल त्रुटि जानकारी वापस कर सकते हैं (हालांकि यह संदर्भ द्वारा पारित "आउट" पैरामीटर "त्रुटि का उपयोग करके भी प्राप्त किया जा सकता है)"
  • भाषा आम तौर पर अपवाद की स्थिति में साफ सफाई के प्रबंधन के लिए कुछ सुविधा प्रदान करती है (जावा में / अंत में, C #, RAII में C ++ का उपयोग करके)
  • घटना में कोई अपवाद नहीं फेंका गया है, निष्पादन कभी-कभी रिटर्न कोड की जांच करने से तेज हो सकता है
  • जावा में, जाँच किए गए अपवादों को घोषित या पकड़ा जाना चाहिए (हालाँकि यह एक कारण हो सकता है)

अपवादों का उपयोग न करने के कारण:

  • कभी-कभी यह ओवरकिल हो जाता है यदि त्रुटि हैंडलिंग सरल है
  • यदि अपवादों को प्रलेखित या घोषित नहीं किया जाता है, तो उन्हें कॉलिंग कोड द्वारा अनकैप्ड किया जा सकता है, जो कि इससे भी बदतर हो सकता है यदि कॉलिंग कोड ने केवल रिटर्न कोड को अनदेखा किया (आवेदन निकास बनाम मूक विफलता - जो कि परिदृश्य पर निर्भर हो सकता है)
  • C ++ में, अपवाद का उपयोग करने वाला कोड सुरक्षित होना चाहिए (भले ही आप उन्हें फेंक या पकड़ न लें, लेकिन फेंकने वाले फ़ंक्शन को अप्रत्यक्ष रूप से कॉल करें)
  • C ++ में, यह बताना मुश्किल है कि कोई फ़ंक्शन कब फेंक सकता है, इसलिए यदि आप उनका उपयोग करते हैं, तो आपको अपवाद सुरक्षा के बारे में पागल होना चाहिए
  • रिटर्न फ्लैग की जांच करने की तुलना में अपवादों को फेंकना और पकड़ना आम तौर पर काफी महंगा होता है

सामान्य तौर पर, मैं C ++ या C # की तुलना में जावा में अपवादों का उपयोग करने के लिए अधिक इच्छुक हूं, क्योंकि मेरा विचार है कि अपवाद, घोषित या नहीं, किसी फ़ंक्शन के औपचारिक इंटरफ़ेस का मौलिक हिस्सा है, क्योंकि आपका अपवाद गारंटी बदल सकता है ब्रेकिंग कोड। जावा IMO में उनका उपयोग करने का सबसे बड़ा लाभ यह है कि आप जानते हैं कि आपका कॉलर MUST अपवाद को संभालता है, और यह सही व्यवहार की संभावना को बेहतर बनाता है।

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

ध्यान दें कि जावा सामान्य और रनटाइम अपवादों के बीच का अंतर बनाता है जिसमें बाद की आवश्यकता को घोषित नहीं किया जाता है। मैं केवल रनटाइम अपवाद कक्षाओं का उपयोग करूँगा जब आप जानते हैं कि त्रुटि कार्यक्रम में बग का परिणाम है।


5

अपवाद कक्षाएं "सामान्य" कक्षाओं की तरह हैं। आप एक नया वर्ग बनाते हैं जब यह "एक अलग प्रकार की वस्तु होती है, विभिन्न क्षेत्रों और विभिन्न कार्यों के साथ"।

अंगूठे के एक नियम के रूप में, आपको अपवादों की संख्या और अपवादों की बारीकियों के बीच संतुलन का प्रयास करना चाहिए। यदि आपकी विधि 4-5 से अधिक भिन्न अपवादों को फेंकती है, तो आप उनमें से कुछ को अधिक "सामान्य" अपवादों में मर्ज कर सकते हैं, (उदाहरण के लिए आपके मामले में "AuthenticationFailedException"), और जो गलत हुआ, उसे विस्तार से अपवाद संदेश का उपयोग करके। जब तक आपका कोड उनमें से प्रत्येक को अलग तरह से संभालता है, आपको कई अपवाद कक्षाएं बनाने की आवश्यकता नहीं है। और अगर ऐसा होता है, तो आपको त्रुटि के साथ एक एनम वापस करना चाहिए जो कि हुआ। यह इस तरह से थोड़ा साफ है।


5

यदि यह एक लूप के अंदर चल रहा कोड है जो कि बार-बार अपवाद का कारण होगा, तो अपवादों को फेंकना अच्छी बात नहीं है, क्योंकि वे बड़े एन के लिए बहुत धीमी गति से होते हैं। लेकिन प्रदर्शन अपवाद न होने पर कस्टम अपवादों को फेंकने में कुछ भी गलत नहीं है। एक मुद्दा। बस यह सुनिश्चित करें कि आपके पास एक आधार अपवाद है जो वे सभी विरासत में प्राप्त करते हैं, जिन्हें बेसएक्स अपवाद या ऐसा कुछ कहा जाता है। BaseException को System.Exception इनहेरिट करता है, लेकिन आपके सभी अपवाद BaseException इनहेरिट करते हैं। आपके पास समान प्रकारों को समूहीकृत करने के लिए अपवाद प्रकारों का एक पेड़ भी हो सकता है, लेकिन यह ओवरकिल हो भी सकता है और नहीं भी।

तो, संक्षिप्त उत्तर यह है कि यदि यह एक महत्वपूर्ण प्रदर्शन दंड का कारण नहीं बनता है (जो इसे तब तक नहीं करना चाहिए जब तक कि आप बहुत सारे अपवाद नहीं फेंक रहे हों), तो आगे बढ़ें।


मुझे वास्तव में एक लूप के अंदर के अपवादों के बारे में आपकी टिप्पणी पसंद आई और मैंने इसे स्वयं आजमाया। मैंने एक लूप int.MaxValueबार चलने वाला एक नमूना कार्यक्रम लिखा और उसमें 'डिवाइड बाय ज़ीरो' अपवाद पैदा किया। आईएफ / ईएलएसई संस्करण, जिसमें मैं जाँच कर रहा था कि डिवीजन ऑपरेशन से पहले लाभांश शून्य नहीं है , 6082 एमएस और 15407722 टिक्स में पूरा हुआ जबकि टीआरवाई / कैटच संस्करण, जिसमें मैं अपवाद उत्पन्न कर रहा था और अपवाद को पकड़ रहा था , 28174385 में पूरा हुआ। एमएस और 71371326155 टिक: यदि / और संस्करण की तुलना में 4632 गुना अधिक।
user1451111

3

मैं जपलॉक के तरीके से सहमत हूं - जब आप किसी ऑपरेशन के परिणाम के बारे में अनिश्चित होते हैं तो एक तीखा फेंक देते हैं। एपीआई के लिए कॉल, फ़ाइल सिस्टम तक पहुँचने, डेटाबेस कॉल, आदि कभी भी आप अपनी प्रोग्रामिंग भाषाओं की "सीमाओं" से आगे बढ़ रहे हैं।

मैं जोड़ना चाहूंगा, मानक अपवाद फेंकने के लिए स्वतंत्र महसूस करूंगा। जब तक आप कुछ "अलग" करने के लिए नहीं जा रहे हैं (नजरअंदाज करें, ईमेल करें, लॉग करें, उस ट्विटर व्हेल चित्र को दिखाएं, आदि), तब कस्टम अपवादों से परेशान न हों।


3

अपवादों को फेंकने के लिए अंगूठे का नियम बहुत सरल है। आप ऐसा तब करते हैं जब आपका कोड एक UNRECOVERABLE INVALID अवस्था में प्रवेश कर जाता है। यदि डेटा से छेड़छाड़ की जाती है या आप उस संसाधन तक वापस नहीं लौट सकते हैं जो उस बिंदु तक आया है, तो आपको इसे समाप्त करना होगा। वास्तव में आप और क्या कर सकते हैं? आपका प्रसंस्करण तर्क अंततः कहीं और विफल हो जाएगा। यदि आप किसी तरह ठीक हो सकते हैं तो ऐसा करें और अपवाद को न फेंकें।

अपने विशेष मामले में यदि आप कुछ पैसे निकालने के लिए मजबूर थे जैसे कि पैसे निकालना स्वीकार करते हैं और उसके बाद ही उपयोगकर्ता / पैस्वर्ड की जांच करें, तो आपको अपवाद को फेंकने की प्रक्रिया को समाप्त करना चाहिए ताकि यह सूचित किया जा सके कि कुछ बुरा हुआ है और आगे नुकसान को रोका जा सकता है।


2

सामान्य तौर पर आप किसी भी चीज़ के लिए एक अपवाद फेंकना चाहते हैं जो आपके आवेदन में हो सकता है जो "असाधारण" है

आपके उदाहरण में, वे दोनों अपवाद ऐसे दिखते हैं जैसे आप उन्हें पासवर्ड / उपयोगकर्ता नाम सत्यापन के माध्यम से बुला रहे हैं। उस स्थिति में यह तर्क दिया जा सकता है कि यह वास्तव में असाधारण नहीं है कि कोई व्यक्ति किसी उपयोगकर्ता नाम / पासवर्ड को गलत करेगा।

वे आपके यूएमएल के मुख्य प्रवाह के "अपवाद" हैं लेकिन प्रसंस्करण में अधिक "शाखाएं" हैं।

यदि आपने अपनी पासवार्ड फ़ाइल या डेटाबेस तक पहुँचने का प्रयास किया है और ऐसा नहीं कर सकते हैं, तो यह एक असाधारण मामला होगा और अपवाद को फेंकने का वारंट होगा।


" यदि आपने अपनी पासवार्ड फ़ाइल या डेटाबेस तक पहुँचने का प्रयास किया है और ऐसा नहीं कर सकते हैं, तो यह एक असाधारण मामला होगा और अपवाद को वारंट करेगा। " सीधे फ़ाइल तक पहुंचने से पहले उनका उपयोग क्यों नहीं किया जाता है!
user1451111

2

सबसे पहले, यदि आपके एपीआई के उपयोगकर्ताओं को विशिष्ट, ठीक-ठीक विफलताओं में दिलचस्पी नहीं है, तो उनके लिए विशिष्ट अपवाद होने का कोई मूल्य नहीं है।

चूंकि यह अक्सर यह जानना संभव नहीं है कि आपके उपयोगकर्ताओं के लिए क्या उपयोगी हो सकता है, एक बेहतर दृष्टिकोण विशिष्ट अपवाद होना है, लेकिन यह सुनिश्चित करें कि वे एक सामान्य वर्ग (जैसे, एसटी :: अपवाद या सी ++ में इसके डेरिवेटिव) से विरासत में मिले हैं। यदि वे चुनते हैं तो आपके ग्राहक को विशिष्ट अपवादों को पकड़ने की अनुमति मिलती है, या यदि वे परवाह नहीं करते हैं तो अधिक सामान्य अपवाद।


2

अपवाद उन घटनाओं के लिए अभिप्रेत हैं जो असामान्य व्यवहार, त्रुटियां, विफलताएं और ऐसी हैं। इसके बजाय कार्यात्मक तर्क, उपयोगकर्ता त्रुटि, आदि को प्रोग्राम लॉजिक द्वारा नियंत्रित किया जाना चाहिए। चूंकि एक खराब खाता या पासवर्ड लॉगिन दिनचर्या में तर्क प्रवाह का एक अपेक्षित हिस्सा है, इसलिए इसे अपवादों के बिना उन स्थितियों को संभालने में सक्षम होना चाहिए।


2

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


2

मैं कहता हूं कि आम तौर पर हर कट्टरवाद नरक की ओर जाता है।

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

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

तकनीकी अपवाद डेटाबेस सर्वर की तरह वास्तव में अप्रत्याशित अपवाद को दर्शाता है, वेब सेवा से कनेक्शन IOException और इतने पर फेंक दिया।

दूसरी ओर तार्किक अपवादों का उपयोग ऊपरी परतों में कम गंभीर गलत स्थिति को फैलाने के लिए किया जाता है (आमतौर पर कुछ सत्यापन परिणाम)।

कृपया ध्यान दें कि तार्किक प्रवाह को भी कार्यक्रम के प्रवाह को नियंत्रित करने के लिए नियमित आधार पर उपयोग करने का इरादा नहीं है, बल्कि स्थिति को उजागर करने के लिए जब प्रवाह वास्तव में समाप्त होना चाहिए। जावा में उपयोग किए जाने पर, दोनों अपवाद प्रकार RuntimeException हैं उप-वर्ग और त्रुटि हैंडलिंग अत्यधिक पहलू उन्मुख होते हैं।

तो लॉगिन उदाहरण में यह हो सकता है कि प्रमाणीकरण जैसे अपवाद को बनाने और उपयोगकर्ता नाम , जैसे मौजूदा मानों द्वारा ठोस स्थितियों में अंतर करने के लिए बुद्धिमान हो । पासवर्ड आदि। । आप कुछ सामान्य अपवाद हैंडलिंग तंत्र को आसानी से नियोजित कर सकते हैं क्योंकि आपके पास वर्गीकृत अपवाद हैं और बहुत अच्छी तरह से जानते हैं कि उपयोगकर्ता को कैसे और कैसे प्रचार करना है।

उपयोगकर्ता का इनपुट अमान्य होने पर वेब सेवा कॉल के दौरान LogicalException को फेंकने के लिए हमारा विशिष्ट उपयोग है। अपवाद SOAPFault डिटेल में marshalled हो जाता है और फिर क्लाइंट पर फिर से अपवाद के लिए अनारक्षित हो जाता है, जिसके परिणामस्वरूप एक निश्चित वेब पेज इनपुट क्षेत्र पर सत्यापन त्रुटि दिखाने के लिए होता है, क्योंकि अपवाद उस फ़ील्ड के लिए उचित मैपिंग है।

यह निश्चित रूप से एकमात्र स्थिति नहीं है: अपवाद को फेंकने के लिए आपको वेब सेवा को हिट करने की आवश्यकता नहीं है। आप किसी भी असाधारण स्थिति में ऐसा करने के लिए स्वतंत्र हैं (जैसे कि आपको फेल होने की जरूरत है) - यह सब आपके विवेक पर है।


2

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


1

एक अपवाद को फेंकने से बचने का मुख्य कारण यह है कि अपवाद को फेंकने के साथ बहुत सारे ओवरहेड शामिल हैं।

राज्यों के नीचे एक बात यह है कि एक अपवाद एक असाधारण स्थिति और त्रुटियों के लिए है।

एक गलत उपयोगकर्ता नाम आवश्यक रूप से एक प्रोग्राम त्रुटि नहीं बल्कि एक उपयोगकर्ता त्रुटि है ...

यहाँ .NET के अपवादों के लिए एक अच्छा शुरुआती बिंदु है: http://msdn.microsoft.com/en-us/library/ms229030(VS.80).aspx


1

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

संभवतः उससे अधिक महत्वपूर्ण, अपवाद असाधारण स्थितियों के लिए हैं। उन्हें सामान्य नियंत्रण प्रवाह के लिए उपयोग नहीं किया जाना चाहिए, क्योंकि इससे आपके कोड की पठनीयता को नुकसान पहुंचेगा।


1

मेरे पास तीन प्रकार की शर्तें हैं जिन्हें मैं पकड़ता हूं।

  1. खराब या अनुपलब्ध इनपुट अपवाद नहीं होना चाहिए। संदेशों के साथ एक ही पृष्ठ पर पता लगाने, सेट करने और वापस भेजने के लिए क्लाइंट साइड जेएस और सर्वर साइड रेगेक्स दोनों का उपयोग करें।

  2. AppException। यह आमतौर पर एक अपवाद है जिसे आप अपने कोड में पहचानते हैं और फेंकते हैं। दूसरे शब्दों में, ये वे हैं जिनकी आप अपेक्षा करते हैं (फ़ाइल मौजूद नहीं है)। इसे लॉग करें, संदेश सेट करें, और सामान्य त्रुटि पृष्ठ पर वापस अग्रेषित करें। इस पृष्ठ में आमतौर पर जानकारी होती है कि क्या हुआ।

  3. अप्रत्याशित अपवाद। ये वे हैं जिनके बारे में आप नहीं जानते हैं। विवरण के साथ लॉग इन करें और उन्हें एक सामान्य त्रुटि पृष्ठ पर अग्रेषित करें।

उम्मीद है की यह मदद करेगा


1

आपके उदाहरण के साथ सुरक्षा जब्त की गई है: आपको एक हमलावर को यह नहीं बताना चाहिए कि उपयोगकर्ता नाम मौजूद है, लेकिन पासवर्ड गलत है। यह अतिरिक्त जानकारी है जिसे आपको साझा करने की आवश्यकता नहीं है। केवल यह कहें कि "उपयोगकर्ता नाम या पासवर्ड गलत है।"


1

सरल उत्तर है, जब भी कोई ऑपरेशन असंभव होता है (या तो आवेदन के कारण या क्योंकि यह व्यापारिक तर्क का उल्लंघन होगा)। यदि कोई विधि लागू की जाती है और यह करना असंभव है कि विधि क्या करने के लिए लिखी गई है, तो अपवाद को फेंक दें। एक अच्छा उदाहरण यह है कि निर्माणकर्ता हमेशा ArgumentException को फेंक देते हैं यदि आपूर्ति मापदंडों का उपयोग करके एक उदाहरण नहीं बनाया जा सकता है। एक अन्य उदाहरण InvalidOperationException है, जिसे तब फेंक दिया जाता है जब किसी अन्य सदस्य या वर्ग के सदस्यों की स्थिति के कारण कोई ऑपरेशन नहीं किया जा सकता है।

आपके मामले में, यदि लॉगिन (उपयोगकर्ता नाम, पासवर्ड) जैसी कोई विधि लागू की जाती है, यदि उपयोगकर्ता नाम मान्य नहीं है, तो यह वास्तव में सही है कि पासवर्ड गलत है तो UserNameNotValidException, या PasswordNotCorrectException को फेंकना सही है। उपयोगकर्ता को दिए गए पैरामीटर (ओं) का उपयोग करके लॉग इन नहीं किया जा सकता है (अर्थात यह असंभव है क्योंकि यह प्रमाणीकरण का उल्लंघन करेगा), इसलिए एक अपवाद फेंकें। हालाँकि, मुझे आपके दो अपवाद ArgumentException से विरासत में मिल सकते हैं।

यह कहते हुए कि, यदि आप एक अपवाद को फेंकना नहीं चाहते हैं क्योंकि एक लॉगिन विफलता बहुत सामान्य हो सकती है, तो एक रणनीति इसके बजाय एक ऐसी विधि का निर्माण करना है जो विभिन्न प्रकारों का प्रतिनिधित्व करती है जो विभिन्न विफलताओं का प्रतिनिधित्व करते हैं। यहाँ एक उदाहरण है:

{ // class
    ...

    public LoginResult Login(string user, string password)
    {
        if (IsInvalidUser(user))
        {
            return new UserInvalidLoginResult(user);
        }
        else if (IsInvalidPassword(user, password))
        {
            return new PasswordInvalidLoginResult(user, password);
        }
        else
        {
            return new SuccessfulLoginResult();
        }
    }

    ...
}

public abstract class LoginResult
{
    public readonly string Message;

    protected LoginResult(string message)
    {
        this.Message = message;
    }
}

public class SuccessfulLoginResult : LoginResult
{
    public SucccessfulLogin(string user)
        : base(string.Format("Login for user '{0}' was successful.", user))
    { }
}

public class UserInvalidLoginResult : LoginResult
{
    public UserInvalidLoginResult(string user)
        : base(string.Format("The username '{0}' is invalid.", user))
    { }
}

public class PasswordInvalidLoginResult : LoginResult
{
    public PasswordInvalidLoginResult(string password, string user)
        : base(string.Format("The password '{0}' for username '{0}' is invalid.", password, user))
    { }
}

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

यहाँ एक उदाहरण में अपवादों से बचने का उदाहरण दिया गया है, जैसे कि आजमाए गए () पैटर्न का उपयोग करके:

public class ValidatedLogin
{
    public readonly string User;
    public readonly string Password;

    public ValidatedLogin(string user, string password)
    {
        if (IsInvalidUser(user))
        {
            throw new UserInvalidException(user);
        }
        else if (IsInvalidPassword(user, password))
        {
            throw new PasswordInvalidException(password);
        }

        this.User = user;
        this.Password = password;
    }

    public static bool TryCreate(string user, string password, out ValidatedLogin validatedLogin)
    {
        if (IsInvalidUser(user) || 
            IsInvalidPassword(user, password))
        {
            return false;
        }

        validatedLogin = new ValidatedLogin(user, password);

        return true;
    }
}

1

मेरे दिमाग में, मौलिक प्रश्न यह होना चाहिए कि क्या कोई यह उम्मीद करेगा कि यदि कोई स्थिति होती है तो कॉलर सामान्य कार्यक्रम प्रवाह को जारी रखना चाहेगा। यदि आप नहीं जानते हैं, या तो अलग doSomething और trySomething तरीके हैं, जहां पूर्व रिटर्न एक त्रुटि देता है और बाद वाला नहीं होता है, या एक रूटीन है जो यह इंगित करने के लिए एक पैरामीटर को स्वीकार करता है कि क्या अपवाद विफल होने पर फेंक दिया जाना चाहिए)। रिमोट सिस्टम पर कमांड भेजने और प्रतिक्रियाओं की रिपोर्ट करने के लिए एक वर्ग पर विचार करें। कुछ कमांड (उदाहरण के लिए पुनः आरंभ) रिमोट सिस्टम को प्रतिक्रिया भेजने का कारण बनेगा, लेकिन फिर एक निश्चित अवधि के लिए गैर-उत्तरदायी होगा। इस प्रकार "पिंग" कमांड भेजने में सक्षम होना और यह पता लगाना उपयोगी है कि क्या रिमोट सिस्टम बिना किसी अपवाद के फेंकने के लिए उचित समय पर प्रतिक्रिया करता है, यदि वह ऐसा नहीं करता है ' टी (कॉलर शायद उम्मीद करेंगे कि पहले कुछ "पिंग" प्रयास विफल होंगे, लेकिन एक अंततः काम करेगा)। दूसरी ओर, यदि किसी के पास कमांड का क्रम है जैसे:

  exchange_command ("ओपन टेम्पोफाइल");
  exchange_command ("अस्थायी डेटा लिखें {जो कुछ भी हो");
  exchange_command ("अस्थायी डेटा लिखें {जो कुछ भी हो");
  exchange_command ("अस्थायी डेटा लिखें {जो कुछ भी हो");
  exchange_command ("अस्थायी डेटा लिखें {जो कुछ भी हो");
  exchange_command ("नज़दीकी अस्थायी");
  exchange_command ("वास्तविक करने के लिए tempfile की प्रतिलिपि बनाएँ");

कोई भी पूरे ऑपरेशन को रद्द करने के लिए किसी भी ऑपरेशन की विफलता चाहेगा। हालांकि यह सुनिश्चित करने के लिए कि प्रत्येक ऑपरेशन की जांच कर सकता है, यह सफल होने के लिए Exchange_command () रूटीन को अपवाद के रूप में अधिक उपयोगी है यदि कोई कमांड विफल रहता है।

वास्तव में, उपरोक्त परिदृश्य में, विफलता-हैंडलिंग मोड की एक संख्या का चयन करने के लिए एक पैरामीटर होना मददगार हो सकता है: कभी भी अपवाद न फेंकें, केवल संचार त्रुटियों के लिए अपवाद फेंकें, या किसी भी मामले में अपवाद फेंकें जहां एक कमांड "सफलता नहीं लौटाता है।" “संकेत।


1

अपवादों का उपयोग करने के लिए "PasswordNotCorrectException" एक अच्छा उदाहरण नहीं है। उपयोगकर्ताओं को अपने पासवर्ड गलत होने की उम्मीद है, इसलिए यह शायद ही एक अपवाद IMHO है। आप शायद इससे उबर भी सकते हैं, एक अच्छा त्रुटि संदेश दिखा रहा है, इसलिए यह सिर्फ वैधता जांच है।

अनचाहे अपवाद अंततः निष्पादन को रोक देंगे - जो अच्छा है। यदि आप गलत, अशक्त या त्रुटि कोड लौटा रहे हैं, तो आपको अपने आप से कार्यक्रम की स्थिति से निपटना होगा। यदि आप कहीं स्थितियां जांचना भूल जाते हैं, तो आपका प्रोग्राम गलत डेटा के साथ चालू रह सकता है, और आपके पास एक मुश्किल समय हो सकता है कि क्या हुआ और कहां हुआ ।

बेशक, आप खाली कैच स्टेटमेंट के साथ एक ही समस्या का कारण बन सकते हैं, लेकिन कम से कम उन लोगों को स्पॉट करना आसान है और आपको तर्क को समझने की आवश्यकता नहीं है।

अतः अंगूठे के नियम के रूप में:

जहाँ आप नहीं चाहते हैं, उनका उपयोग करें या बस एक त्रुटि से उबर नहीं सकते।


0

आप उस स्थिति के लिए थोड़े सामान्य अपवादों का उपयोग कर सकते हैं। उदाहरण के लिए, ArgumentException का उपयोग तब किया जाता है जब किसी भी विधि के लिए कुछ भी गलत हो जाता है (ArgumentNullException के अपवाद के साथ)। आम तौर पर आपको अपवादों की आवश्यकता नहीं होगी जैसे कि लेसोथेरोएक्स अपवाद, नॉटप्राइमनेबसेफेसेप्शन आदि। अपने तरीके के उपयोगकर्ता के बारे में सोचें। वह परिस्थितियों की संख्या जो वह विशेष रूप से संभालना चाहेगी वह उस प्रकार के अपवादों की संख्या के बराबर है जिसे आपकी विधि को फेंकने की आवश्यकता है। इस तरह, आप यह निर्धारित कर सकते हैं कि आपके पास कितने विस्तृत अपवाद होंगे।

वैसे, अपवादों से बचने के लिए हमेशा अपने पुस्तकालयों के उपयोगकर्ताओं के लिए कुछ तरीके प्रदान करने का प्रयास करें। TryParse एक अच्छा उदाहरण है, यह मौजूद है ताकि आपको int.Parse का उपयोग न करना पड़े और अपवाद को पकड़ न सके। आपके मामले में, आप यह जांचने के लिए कुछ तरीके प्रदान कर सकते हैं कि उपयोगकर्ता का नाम वैध है या पासवर्ड सही है, इसलिए आपके उपयोगकर्ताओं (या आपको) को बहुत सारी अपवाद हैंडलिंग नहीं करनी होंगी। यह उम्मीद है कि अधिक पठनीय कोड और बेहतर प्रदर्शन का परिणाम देगा।


0

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

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

0

अपवाद के दो मुख्य वर्ग हैं:

1) सिस्टम अपवाद (जैसे डेटाबेस कनेक्शन खो गया) या 2) उपयोगकर्ता अपवाद। (उदा। उपयोगकर्ता इनपुट सत्यापन, 'पासवर्ड गलत है')

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

            If TypeName(ex) = "UserException" Then
               Display(ex.message)
            Else
               DisplayError("An unexpected error has occured, contact your help  desk")                   
               LogError(ex)
            End If

0

अपवाद के लिए उपयुक्त है या नहीं यह तय करते समय सोचने वाली कुछ उपयोगी बातें:

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

  2. क्या यह ईवेंट कुछ ऐसा है जिसे आप त्रुटि लॉग में देखना चाहेंगे? प्रत्येक अपवाद त्रुटि लॉग के लिए नहीं लिखा गया है, लेकिन यह पूछना उपयोगी है कि त्रुटि लॉग में यह प्रविष्टि उपयोगी होगी - यानी, आप इसके बारे में कुछ करने की कोशिश करेंगे, या वह कचरा होगा जिसे आप अनदेखा करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.