बिना किसी अपवाद के अनियंत्रित बनाम जाँच की गई ... विपरीत मान्यताओं का सबसे अच्छा अभ्यास


10

अपवाद को सही ढंग से व्यक्त करने और संभालने के लिए एक प्रणाली के लिए कई आवश्यकताएं हैं। अवधारणा को लागू करने के लिए भाषा चुनने के लिए कई विकल्प भी हैं।

अपवादों के लिए आवश्यकताएँ (किसी विशेष क्रम में नहीं):

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

  2. असाधारण अपवादों को संचारित करें : यह एक स्पष्ट स्थिति है, जो किसी कार्य को उन स्थितियों को व्यक्त करने की अनुमति देती है, जो कि अपेक्षित कार्यक्षमता को कार्य करने से रोकती हैं। मेरी राय में ऐसी स्थितियों की तीन बड़ी श्रेणियां हैं:

    2.1 कोड में कुछ डेटा अमान्य होने का कारण बनता है।

    2.2 कॉन्फ़िगरेशन या अन्य बाहरी संसाधनों में समस्याएं।

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

  3. इसे संभालने के लिए कोड के लिए पर्याप्त जानकारी प्रदान करें : अपवादों को कैली को पर्याप्त जानकारी प्रदान करनी चाहिए ताकि वह प्रतिक्रिया कर सके और संभवतः स्थिति को संभाल सके। जानकारी भी पर्याप्त होनी चाहिए ताकि लॉग इन करने पर यह अपवाद प्रोग्रामर को पर्याप्त संदर्भ प्रदान कर सके और आपत्तिजनक कथनों की पहचान कर सके और समाधान प्रदान कर सके।

  4. प्रोग्रामर को अपने कोड के निष्पादन की वर्तमान स्थिति के बारे में आत्मविश्वास प्रदान करें : प्रोग्रामर के रास्ते से बाहर रहने के दौरान आवश्यक सुरक्षा उपायों को प्रदान करने के लिए एक सॉफ्टवेयर सिस्टम की अपवाद हैंडलिंग क्षमताओं को पर्याप्त रूप से मौजूद होना चाहिए ताकि वह कार्य पर केंद्रित रह सकें हाथ।

इन्हें कवर करने के लिए विभिन्न भाषाओं में निम्नलिखित तरीके लागू किए गए हैं:

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

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

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

तो सवाल यह है:

इस मामले में आपका अनुभव क्या है और आपके अनुसार, एक भाषा के लिए एक अच्छा अपवाद हैंडलिंग सिस्टम बनाने के लिए सबसे अच्छा उम्मीदवार क्या है?


संपादित करें: इस प्रश्न को लिखने के कुछ ही मिनटों बाद मैं इस पोस्ट पर आया , डरावना!


2
"यह बहुत ही समस्याओं से ग्रस्त होगा जैसा कि थका हुआ अपवाद और आपके चेहरे में लगातार होने के रूप में जाँच किया गया है": वास्तव में नहीं: उचित भाषा समर्थन के साथ आपको केवल "सफलता पथ" प्रोग्राम करना होगा, अंतर्निहित भाषा मशीनरी के साथ प्रचार-प्रसार का ख्याल रखना होगा। त्रुटियों।
जियोर्जियो

"एक भाषा के पास एक दस्तावेज़ का अपवाद होना चाहिए जो एक एपीआई फेंक सकता है।" - weeeel। C ++ में "हमने" सीखा कि यह वास्तव में काम नहीं करता है। आप सभी उपयोगी रूप से बता सकते हैं कि क्या कोई एपीआई किसी अपवाद को फेंक सकता है। (जो वास्तव में एक लंबी कहानी को काट रहा है, लेकिन मुझे लगता है कि noexceptC ++ में कहानी को देखना C # और Java में EH के लिए बहुत अच्छी अंतर्दृष्टि प्रदान कर सकता है।)
मार्टिन बा

जवाबों:


10

C ++ के शुरुआती दिनों में हमने पाया कि बिना किसी प्रकार की जेनेरिक प्रोग्रामिंग के, दृढ़ता से टाइप की जाने वाली भाषाएं बहुत ही अस्पष्ट थीं। हमने यह भी पाया कि अपवादों की जाँच की और सामान्य प्रोग्रामिंग एक साथ अच्छी तरह से काम नहीं किया, और जाँच अपवादों को अनिवार्य रूप से छोड़ दिया गया था।

मल्टीसेट रिटर्न प्रकार महान हैं, लेकिन अपवादों के लिए कोई प्रतिस्थापन नहीं है। अपवादों के बिना कोड त्रुटि-जाँच शोर से भरा है।

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


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

3
कैस्केडिंग समस्या के लिए +1। कोई भी प्रणाली / वास्तुकला जो परिवर्तन को मुश्किल बनाती है, केवल बंदर-पैचिंग और गन्दा सिस्टम की ओर ले जाती है, कोई फर्क नहीं पड़ता कि लेखकों ने कितनी अच्छी तरह से डिजाइन किया था।
मैथ्यू एम।

2
@ न्यूटोपियन: टेम्प्लेट वे चीजें करते हैं जो सख्त ऑब्जेक्ट ओरिएंटेशन में नहीं की जा सकती हैं, जैसे कि जेनेरिक कंटेनरों के लिए स्थैतिक प्रकार की सुरक्षा प्रदान करना।
डेविड थॉर्नले

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

7
"अपवादों के बिना कोड त्रुटि-जाँच शोर से भरा है।": मुझे इस बारे में निश्चित नहीं है: हास्केल में आप इसके लिए साधुओं का उपयोग कर सकते हैं और सभी त्रुटि की जाँच शोर हो गया है। "मल्टीस्टेट रिटर्न प्रकार" द्वारा पेश किया गया शोर अपने आप में समाधान की तुलना में प्रोग्रामिंग भाषा की अधिक सीमा है।
जियोर्जियो

9

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

यह वास्तव में मल्टीस्टेट परिणाम प्रकार का एक प्रकार है।

  • एक फ़ंक्शन या तो एक सफलता, या एक त्रुटि देता है। यह दोनों को वापस नहीं कर सकता (जैसा कि एक टपल के साथ होता है)।
  • सभी संभावित त्रुटियों को संक्षिप्त रूप से प्रलेखित किया गया है (कम से कम एफ # में परिणाम प्रकार के साथ भेदभाव किए गए यूनियनों के रूप में)।
  • यदि परिणाम एक सफलता या विफलता थी, तो कॉलर बिना ध्यान दिए परिणाम का उपयोग नहीं कर सकता।

परिणाम प्रकार इस तरह से घोषित किया जा सकता है

type Result<'TSuccess,'TFail> =
| Success of 'TSuccess
| Fail of 'TFail

एक समारोह का परिणाम है कि रिटर्न इस प्रकार या तो एक होगा तो Successया एक Failप्रकार। यह दोनों नहीं हो सकता।

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

// Create an updateUser function that takes an id, and new state
// as input, and updates an existing user.
let updateUser id input =
    validateInput input
    >>= loadUser id
    >>= updateUser input
    >>= saveUser id
    >>= notifyAboutUserUpdated

updateUserसमारोह के बाद एक इन कार्यों में से प्रत्येक कहता है, और उनमें से प्रत्येक को विफल कर सकते हैं। यदि वे सभी सफल होते हैं, तो अंतिम फ़ंक्शन का परिणाम वापस आ जाता है। यदि कोई फ़ंक्शन विफल हो जाता है, तो उस फ़ंक्शन का परिणाम समग्र updateUserफ़ंक्शन का परिणाम होगा । यह सभी कस्टम >> = ऑपरेटर द्वारा नियंत्रित किया जाता है।

उपरोक्त उदाहरण में, त्रुटि प्रकार हो सकते हैं

type UserValidationErrorType =
| InvalidEmail of string
| MissingFirstName of string
... etc

type DbErrorType =
| RecordNotFound of int
| ConcurrencyError of int

type UpdateUserErrorType =
| InvalidInput of UserValidationErrorType
| DbError of DbErrorType

यदि updateUserफ़ंक्शन का कॉलर स्पष्ट रूप से फ़ंक्शन से सभी संभावित त्रुटियों को नहीं संभालता है, तो संकलक एक चेतावनी जारी करेगा। तो आपके पास सब कुछ प्रलेखित है।

हास्केल में, एक doसंकेतन है जो कोड को क्लीनर भी बना सकता है।


2
बहुत अच्छा जवाब और संदर्भ (रेलवे-उन्मुख प्रोग्रामिंग), +1। आप हास्केल के doसंकेतन का उल्लेख करना चाह सकते हैं , जिसके परिणामस्वरूप कोड भी साफ हो जाता है।
जियोर्जियो

1
@ जियोर्जियो - मैंने अब किया, लेकिन मैंने हास्केल के साथ काम नहीं किया, केवल एफ #, इसलिए मैं वास्तव में इसके बारे में बहुत कुछ नहीं लिख सका। लेकिन आप चाहें तो जवाब में जोड़ सकते हैं।
पीट

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

2
Railway Oriented Programmingवास्तव में monadic व्यवहार है।
डेनिथ

5

मुझे पीट का जवाब बहुत अच्छा लगता है और मैं कुछ विचार और एक उदाहरण जोड़ना चाहूंगा। रॉबर्ट हार्पर द्वारा धारा 29.3, पृष्ठ 243, 244 के अंत में मानक एमएल में प्रोग्रामिंग में अपवाद बनाम वापसी विशेष त्रुटि मूल्यों के उपयोग के बारे में एक बहुत ही दिलचस्प चर्चा पाई जा सकती है ।

समस्या यह है fकि किसी प्रकार के मान को लौटाने वाले आंशिक फ़ंक्शन को लागू किया जाए t। एक समाधान यह है कि फ़ंक्शन का प्रकार है

f : ... -> t

और जब कोई संभावित परिणाम न हो तो एक अपवाद फेंक दें। दूसरा समाधान प्रकार के साथ एक फ़ंक्शन को लागू करना है

f : ... -> t option

और SOME vसफलता पर, और NONEअसफलता पर।

यहाँ पुस्तक से पाठ है, पाठ को और अधिक सामान्य बनाने के लिए स्वयं द्वारा किए गए छोटे अनुकूलन के साथ (पुस्तक एक विशेष उदाहरण को संदर्भित करता है)। संशोधित पाठ इटैलिक में लिखा गया है

दो समाधानों के बीच व्यापार-बंद क्या हैं?

  1. विकल्प प्रकारों के आधार पर समाधान फ़ंक्शन fके प्रकार में विफलता की संभावना को स्पष्ट करता है । यह प्रोग्रामर को कॉल के परिणाम पर केस विश्लेषण का उपयोग करके विफलता के लिए स्पष्ट रूप से परीक्षण करने के लिए मजबूर करता है। प्रकार चेकर यह सुनिश्चित करेगा कि t optionजहांt अपेक्षित है वहां कोई भी उपयोग नहीं कर सकता है। अपवादों पर आधारित समाधान स्पष्ट रूप से इसके प्रकार में विफलता का संकेत नहीं देता है। हालांकि, प्रोग्रामर को असफलता से निपटने के लिए मजबूर किया जाता है, अन्यथा संकलन-समय के बजाय रन-टाइम पर एक अनकैप्ड अपवाद त्रुटि को उठाया जाएगा।
  2. विकल्प प्रकारों के आधार पर समाधान को प्रत्येक कॉल के परिणाम पर एक स्पष्ट मामले के विश्लेषण की आवश्यकता होती है। यदि "अधिकांश" परिणाम सफल होते हैं, तो चेक बेमानी है और इसलिए अत्यधिक महंगा है। अपवादों पर आधारित समाधान इस ओवरहेड से मुक्त है: यह एक "वापसी" के सामान्य पक्षपात के मामले में पक्षपाती है t, बजाय इसके कि "विफलता" के मामले में एक परिणाम नहीं लौटाया जाए । अपवादों का कार्यान्वयन यह सुनिश्चित करता है कि हैंडलर का उपयोग उस मामले में एक स्पष्ट मामले के विश्लेषण से अधिक कुशल है कि सफलता की तुलना में विफलता दुर्लभ है।

[कटौती] सामान्य तौर पर, यदि दक्षता सर्वोपरि है, तो हम अपवादों को प्राथमिकता देते हैं यदि विफलता एक दुर्लभ वस्तु है, और विफलता के अपेक्षाकृत सामान्य होने पर विकल्पों को पसंद करते हैं। यदि, दूसरी ओर, स्थैतिक जाँच सर्वोपरि है, तो विकल्प का उपयोग करना लाभप्रद है क्योंकि टाइप चेकर इस आवश्यकता को लागू करेगा कि प्रोग्रामर विफलता के लिए जाँच करता है, बजाय केवल रन-टाइम में त्रुटि उत्पन्न होने के कारण।

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

इस विचार के बारे में कि रिटर्न प्रकार में त्रुटि का प्रतिनिधित्व करने से कोड में सभी जगह फैले हुए त्रुटि की जांच हो जाती है: यह मामला नहीं है। यहाँ हास्केल में एक छोटा सा उदाहरण है जो इसे दिखाता है।

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

import Text.Read

parseInt :: String -> Maybe Int
parseInt s = readMaybe s :: Maybe Int

safeDiv :: Int -> Int -> Maybe Int
safeDiv n d = if d /= 0 then Just (n `div` d) else Nothing

toString :: Maybe Int -> String
toString (Just i) = show i
toString Nothing  = "error"

main = do
         -- Get two lines from the terminal.
         nStr <- getLine
         dStr <- getLine

         -- Parse each string and divide.
         let r = do n <- parseInt nStr
                    d <- parseInt dStr
                    safeDiv n d

         -- Print the result.
         putStrLn $ toString r

let ...ब्लॉक में पार्सिंग और डिवीजन का प्रदर्शन किया जाता है । ध्यान दें कि Maybeमोनाड और doसंकेतन का उपयोग करके , केवल सफलता पथ निर्दिष्ट किया जाता है: Maybeमोनाड के शब्दार्थ में त्रुटि मान का प्रसार होता है ( Nothing)। प्रोग्रामर के लिए कोई ओवरहेड नहीं।


2
मुझे लगता है कि इस तरह के मामलों में जहां आप किसी प्रकार के उपयोगी त्रुटि संदेश को प्रिंट करना चाहते हैं, तो यह Eitherप्रकार अधिक उपयुक्त होगा। Nothingयहां आने पर आप क्या करते हैं? आपको बस "त्रुटि" संदेश मिलता है। डिबगिंग के लिए बहुत उपयोगी नहीं है।
सारा

1

मैं चेक किए गए अपवादों का एक बड़ा प्रशंसक बन गया हूं और मैं अपना सामान्य नियम साझा करना चाहता हूं कि उनका उपयोग कब करना है।

मैं इस निष्कर्ष पर पहुंचा हूं कि मूल रूप से 2 प्रकार की त्रुटियां हैं, जिनसे मेरे कोड को निपटना है। ऐसी त्रुटियां हैं जो कोड निष्पादित होने से पहले परीक्षण करने योग्य हैं और ऐसी त्रुटियां हैं जो कोड निष्पादित होने से पहले गैर-परीक्षण योग्य हैं। NullPointerException में कोड निष्पादित होने से पहले एक त्रुटि के लिए एक सरल उदाहरण परीक्षण योग्य है।

//... bad code below.  the runnable variable
// tries to call the run() method before the variable
// is instantiated.  Running the code below will cause
// a NullPointerException.
Runnable runnable = null;
runnable.run();

एक साधारण परीक्षण इस तरह की त्रुटि से बचा सकता है ...

Runnable runnable = null;
...
if (runnable != null)
{   runnable.run(); }

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

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

ऐसे समय होते हैं जब यह तय करना कठिन हो जाता है कि कोड परीक्षण योग्य है या नहीं। उदाहरण के लिए, यदि आप एक दुभाषिया लिख ​​रहे हैं और एक SyntaxException को फेंक दिया जाता है, जब कोड कुछ वाक्यात्मक कारण के लिए निष्पादित करने में विफल रहता है, तो क्या SyntaxException एक जाँच अपवाद या (Java में) एक RuntaxException होनी चाहिए? मैं जवाब दूंगा कि अगर कोड निष्पादित होने से पहले दुभाषिया कोड के सिंटैक्स की जांच करता है, तो अपवाद एक RuntexException होना चाहिए। यदि दुभाषिया केवल कोड 'हॉट' चलाता है और सिंटैक्स त्रुटि करता है, तो मैं कहूंगा कि अपवाद एक जाँच अपवाद होना चाहिए।

मैं स्वीकार करूंगा कि मुझे हमेशा चेक किए गए अपवाद को पकड़ने या फेंकने में खुशी नहीं होती है क्योंकि ऐसे समय हैं जहां मुझे यकीन नहीं है कि मुझे क्या करना है। जाँच किए गए अपवाद एक प्रोग्रामर को संभावित समस्या से सावधान रहने के लिए मजबूर करने का एक तरीका है। जावा में प्रोग्राम करने का एक कारण यह है कि इसमें चेक्ड एक्सेप्शन हैं।


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

अपवाद का उपयोग करना और उन्हें रिटर्न कोड का उपयोग करके बनाम जांचना नहीं है और अंत में उनकी जांच नहीं करना यह सब एक ही कार्डिएक गिरफ्तारी देता है।
न्यूटॉपियन

-1

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

ExpectedException
- AuthorisedException
- EmptySetException
- NoRemainingException
- NoRowsException
- NotFoundException
- ValidationException

अनपेक्षित अपवाद
- संयोजकता अपवाद
- EnvironmentException
- ProgrammerException
- SQLException

उदाहरण

   $valid_types = array('mysql', 'oracle', 'sqlite');
       if (!in_array($type, $valid_types)) {
           throw new ecProgrammerException(
        'The database type specified, %1$s, is invalid. Must be one of: %2$s.',
    $type,
    join(', ', $valid_types)
    );
}

11
यदि अपवाद अपेक्षित है, तो यह वास्तव में अपवाद नहीं है। "NoRowsException"? मेरे लिए नियंत्रण प्रवाह की तरह लगता है, और इसलिए एक अपवाद का खराब उपयोग।
क्वेंटिन-स्टारिन

1
@qes: यह एक अपवाद को बढ़ाने के लिए समझ में आता है जब कोई फ़ंक्शन किसी मान की गणना करने में असमर्थ होता है, उदाहरण के लिए डबल Math.sqrt (डबल वी) या उपयोगकर्ता खोजक (लंबी आईडी)। यह कॉलर को प्रत्येक कॉल के बाद जांच करने के बजाय, जहां यह सुविधाजनक है, त्रुटियों को पकड़ने और संभालने की स्वतंत्रता देता है।
केविन क्लाइन

1
अपेक्षित = नियंत्रण प्रवाह = अपवाद का प्रतिमान। नियंत्रण प्रवाह के लिए अपवाद का उपयोग नहीं किया जाना चाहिए। यदि यह विशिष्ट इनपुट के लिए त्रुटि पैदा करने की उम्मीद है, तो इसे केवल रिटर्न वैल्यू का एक हिस्सा माना जाएगा। तो हमारे पास NANया है NULL
Eonil

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