जावा या C # [बंद] में अपवाद प्रबंधन के लिए सर्वोत्तम अभ्यास


117

मैं अपने आवेदन में अपवादों को कैसे संभालना है, यह तय कर रहा हूं।

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

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

यहाँ एक विशिष्ट विधि का कुछ नमूना कोड (जावा में) है

public boolean doSomething(Object p_somthingToDoOn)
{
    boolean result = false;

    try{
        // if dirty object then clean
        doactualStuffOnObject(p_jsonObject);

        //assume success (no exception thrown)
        result = true;
    }
    catch(Exception Ex)
    {
        //don't care about exceptions
        Ex.printStackTrace();
    }
    return result;
}

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

प्रमुख सवालों के सारांश में:

  1. क्या केवल अपवादों को पकड़ना ठीक है, लेकिन उन्हें बुलबुला बनाना या औपचारिक रूप से सिस्टम को सूचित नहीं करना (या तो लॉग या उपयोगकर्ता की सूचना के माध्यम से)?
  2. अपवादों के लिए कौन सी सर्वोत्तम प्रथाएं हैं जो एक कोशिश / कैच ब्लॉक की आवश्यकता के परिणामस्वरूप नहीं होती हैं?

ऊपर / संपादित करें

सभी प्रतिक्रिया के लिए धन्यवाद, अपवाद प्रबंधन पर कुछ उत्कृष्ट स्रोत ऑनलाइन मिले:

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

इसके अतिरिक्त अत्यधिक कोशिश / कैच के माध्यम से कोड-रोट देखने के लिए या एक अपवाद नहीं देने पर इसका सम्मान (एक अपवाद सिस्टम को चेतावनी दे रहा है, और क्या चेतावनी दी जानी चाहिए?)।

इसके अलावा, यह m3rLinEz की एक सुंदर पसंद है ।

मैं एंडर्स हेजेल्सबर्ग और आप से सहमत हूं कि सबसे ज्यादा कॉल करने वाले केवल इस बात की परवाह करते हैं कि ऑपरेशन सफल है या नहीं।

इस टिप्पणी से अपवादों से निपटने के बारे में सोचने के लिए कुछ प्रश्न सामने आते हैं:

  • यह अपवाद किस बिंदु पर फेंका जा रहा है?
  • इसे संभालने के लिए कैसे समझ में आता है?
  • क्या कॉलर वास्तव में अपवाद के बारे में परवाह करता है या क्या वे केवल परवाह करते हैं कि क्या कॉल सफल हुआ था?
  • एक संभावित अपवाद का प्रबंधन करने के लिए एक फोन करने वाले को मजबूर करने के लिए मजबूर किया जाता है?
  • क्या आप भाषा के मुहावरों के प्रति सम्मानजनक हैं?
    • क्या आपको वास्तव में बूलियन की तरह एक सफलता झंडा वापस करने की आवश्यकता है? रिटर्निंग बूलियन (या इंट) एक जावा की तुलना में सी मानसिकता से अधिक है (जावा में आप सिर्फ अपवाद को संभालेंगे) एक।
    • भाषा से जुड़े त्रुटि प्रबंधन निर्माणों का अनुसरण करें :)!

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

जवाबों:


61

यह मुझे अजीब लगता है कि आप अपवादों को पकड़ना चाहते हैं और उन्हें त्रुटि कोड में बदलना चाहते हैं। आपको क्या लगता है कि कॉलर अपवादों पर त्रुटि कोड पसंद करेगा जब बाद वाला जावा और सी # दोनों में डिफ़ॉल्ट हो?

अपने प्रश्नों के लिए:

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

जैसे कि कोई व्यक्ति अपवादों के बजाय त्रुटि कोड क्यों चाहता है ... मैंने हमेशा सोचा कि यह अजीब था कि HTTP अभी भी त्रुटि कोड का उपयोग करता है, भले ही मेरा एप्लिकेशन अपवाद उत्पन्न कर रहा हो। HTTP मुझे अपवाद के रूप में क्यों नहीं दे सकता है?
तर्जुक

सबसे अच्छा आप अपने त्रुटि कोड को एक
सनक में लपेटना है

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

मुझे लगता है कि यह कहना बेहतर है: "आपको केवल अपवादों को छोड़ देना चाहिए जिसे आप वास्तव में संभाल सकते हैं।"
डिडिएर ए।

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

25

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

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

सामान्य तौर पर मैं निम्नलिखित नियमों का उपयोग करता हूं:

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

मुझे गंध के लिए निम्नलिखित कोड मिलते हैं:

try
{
    //do something
}
catch(Exception)
{
   throw;
}

इस तरह कोड कोई बिंदु नहीं है और इसे शामिल नहीं किया जाना चाहिए।


। अंतिम परियोजना में आपका कोड स्निपेट अनिवार्य था, यह रीकेड था। उन सभी को लॉगिंग ने इसे सबसे खराब बना दिया, मेरी सलाह, अगर आप अपवाद को नहीं संभाल सकते हैं तो इसे निगलने की कोशिश न करें।
स्मोकल

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

कोड एक बिंदु पर कार्य करता है: आप "फेंक" पर एक ब्रेकपॉइंट सेट कर सकते हैं।
रूहोतज़

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

"कोड गंध" उदाहरण का एक निश्चित साइड इफेक्ट है, यहां तक ​​कि सरल रूप में भी। यदि बिंदु के आसपास // do somethingकोई try/finallyब्लॉक शामिल है जो फेंकता है, तो finallyब्लॉक ब्लॉक से पहले निष्पादित होगा catch। बिना किसी try/catchअपवाद के, स्टैक के शीर्ष तक सभी तरह से उड़ जाएगा बिना किसी finallyब्लॉक के निष्पादित किया जा रहा है। यह शीर्ष-स्तरीय हैंडलर को यह तय करने की अनुमति देता है कि finallyब्लॉक को निष्पादित करना है या नहीं ।
डैनियल ईयरविकर

9

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

विफलता और अपवाद

पृष्ठ के निचले भाग में महान संसाधन भी हैं।

मैं एंडर्स हेजेल्सबर्ग और आप से सहमत हूं कि सबसे ज्यादा कॉल करने वाले केवल इस बात की परवाह करते हैं कि ऑपरेशन सफल है या नहीं।

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

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

एक नए संस्करण में एक थ्रो क्लाज के लिए एक नया अपवाद जोड़ने से क्लाइंट कोड टूट जाता है। यह एक इंटरफ़ेस में एक विधि जोड़ने जैसा है। एक इंटरफ़ेस प्रकाशित करने के बाद, यह सभी व्यावहारिक उद्देश्यों के लिए अपरिवर्तनीय है, क्योंकि इसके किसी भी कार्यान्वयन में वे विधियाँ हो सकती हैं जिन्हें आप अगले संस्करण में जोड़ना चाहते हैं। इसलिए आपको इसके बजाय एक नया इंटरफ़ेस बनाना होगा। इसी तरह अपवादों के साथ, आपको या तो एक पूरी नई विधि बनानी होगी जिसे foo2 कहा जाता है जो अधिक अपवादों को फेंकता है, या आपको नए foo में अपवाद D को पकड़ना होगा, और D को A, B, या C में बदलना होगा।

बिल वेनर : लेकिन क्या आप उस मामले में अपना कोड नहीं तोड़ रहे हैं, यहां तक ​​कि बिना किसी अपवाद की भाषा में भी? यदि फू का नया संस्करण एक नया अपवाद फेंकने जा रहा है जिसे ग्राहकों को संभालने के बारे में सोचना चाहिए, तो क्या उनका कोड सिर्फ इस तथ्य से टूटा नहीं है कि उन्हें उस अपवाद की उम्मीद नहीं थी जब उन्होंने कोड लिखा था?

एंडर्स हेजलबर्ग : नहीं, क्योंकि बहुत सारे मामलों में लोग परवाह नहीं करते हैं। वे इनमें से किसी भी अपवाद को संभालने नहीं जा रहे हैं। उनके संदेश लूप के आसपास एक निचला स्तर अपवाद हैंडलर है। वह हैंडलर बस एक संवाद लाने जा रहा है जो कहता है कि क्या गलत हुआ और जारी रहा। प्रोग्रामर अंत में हर जगह कोशिश करके अपने कोड की रक्षा करते हैं, इसलिए यदि कोई अपवाद होता है, तो वे सही ढंग से वापस करेंगे, लेकिन वे वास्तव में अपवादों को संभालने में रुचि नहीं रखते हैं।

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

संपादित करें: कनवर्ज़न पर अधिक विवरण जोड़े गए


इसके लिए धन्यवाद! मैंने आपके उत्तर के बारे में जानकारी के साथ अपना प्रश्न अपडेट किया!
अटारीपेठ

ऐसा लगता है जैसे मिस्टर हेजेल्सबर्ग पोकेमॉन अपवाद हैंडलिंग को सही ठहरा रहे हैं। जावा और सी # में अपवादों के डिजाइन के साथ एक बड़ी समस्या यह है कि बहुत अधिक जानकारी एक अपवाद के प्रकार में एन्कोडेड है, जबकि जानकारी को ऐसे अपवादों में संग्रहीत किया जाना चाहिए जो किसी सुसंगत तरीके से उपलब्ध नहीं है। अपवाद कॉल स्टैक को तब तक प्रचारित करना चाहिए जब तक कि सभी असामान्य स्थितियों का प्रतिनिधित्व नहीं किया जाता है, जो हल हो चुके हैं; दुर्भाग्य से, एक अपवाद का प्रकार - भले ही मान्यता प्राप्त हो - यह इंगित करने के लिए बहुत कम है कि क्या कोई स्थिति हल हो गई है। अगर एक अपवाद अपरिचित है ...
सुपरकैट

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

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

8

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

अंगूठे के नियमों के रूप में, इन दिशानिर्देशों के अलावा कुछ विशेष क्रम में अपवाद हैंडलिंग होनी चाहिए:

  • स्थिरता बनाए रखने के लिए, हमेशा अपवादों को लॉग इन करें ताकि जब आप बग देखना शुरू करें, तो लॉग आपको उस जगह की ओर इशारा करने में सहायता करेगा जहां आपके बग की संभावना शुरू हुई है। कभी मत छोड़ो printStackTrace()या इसे पसंद मत करो, संभावना है कि आपके उपयोगकर्ताओं में से एक को अंततः उन स्टैक के निशान मिलेंगे, और बिल्कुल शून्य ज्ञान होगा कि इसके साथ क्या करना है।
  • उन अपवादों को पकड़ें जिन्हें आप और केवल वे ही संभाल सकते हैं, और उन्हें संभाल सकते हैं , बस उन्हें स्टैक को न फेंकें।
  • हमेशा एक विशिष्ट अपवाद वर्ग को पकड़ें, और आम तौर पर आपको कभी भी प्रकार नहीं पकड़ना चाहिए Exception, आप अन्यथा महत्वपूर्ण अपवादों को निगलने की संभावना रखते हैं।
  • कभी (कभी) कैच Errors !! , जिसका अर्थ है: कभी पकड़ Throwableएस के रूप में Errorरों बाद के उपवर्गों हैं। Errorऐसी समस्याएं हैं जिन्हें आप संभवतः कभी नहीं संभाल पाएंगे (जैसे OutOfMemory, या अन्य JVM मुद्दे)

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


जाँच किए गए अपवाद C # में कोई समस्या नहीं है क्योंकि यह उनके पास नहीं है।
cletus

3
Imho, कभी-कभी त्रुटियों को पकड़ने के लिए अच्छा होता है: मैंने एक बहुत ही स्मृति गहन जावा ऐप जो मैंने लिखा था, उसे पुनः प्राप्त करता हूं। मैंने आउटऑफमेरी-एक्स को पकड़ा, और उपयोगकर्ता को एक संदेश दिखाया कि वह स्मृति से बाहर है, कि उसे अन्य कार्यक्रमों को छोड़ देना चाहिए और उसे बताया कि jvm को और अधिक हीप स्पेस के साथ कैसे शुरू किया जाए। मुझे लगता है कि इससे मदद मिली।
लीना शिममेल

5

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


3

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

पूर्व।

try
{
   sendMessage();

   if(message == success)
   {
       doStuff();
   }
   else if(message == failed)
   {
       throw;
   }
}
catch(Exception)
{
    logAndRecover();
}

यह कोड मुझे बर्फ़ बनाता है। IMO आपको अपवादों से उबरना नहीं चाहिए जब तक कि इसका महत्वपूर्ण कार्यक्रम न हो। यदि आपके अपवादों को फेंक दें तो बुरी चीजें हो रही हैं।


2

उपरोक्त सभी उचित लगते हैं, और अक्सर आपके कार्यस्थल में एक नीति हो सकती है। हमारे स्थान पर हमने अपवाद के प्रकारों को परिभाषित किया है: SystemException(अनियंत्रित) और ApplicationException(जाँच)।

हम सहमत हुए हैं कि SystemExceptionपुनर्प्राप्त होने की संभावना नहीं है और शीर्ष पर एक बार संभाला जाएगा। आगे संदर्भ प्रदान करने के लिए, हमारे SystemExceptionरों इंगित करने के लिए वे कहाँ हुआ, जैसे exteneded कर रहे हैं RepositoryException, ServiceEceptionआदि

ApplicationExceptions का व्यावसायिक अर्थ हो सकता है जैसे InsufficientFundsExceptionऔर ग्राहक कोड द्वारा नियंत्रित किया जाना चाहिए।

Witohut एक ठोस उदाहरण है, आपके कार्यान्वयन पर टिप्पणी करना मुश्किल है, लेकिन मैं कभी भी रिटर्न कोड का उपयोग नहीं करूंगा, वे एक रखरखाव मुद्दा हैं। आप एक अपवाद को निगल सकते हैं, लेकिन आपको यह तय करने की आवश्यकता है कि, और हमेशा ईवेंट और स्टैकट्रेस लॉग क्यों करें। अन्त में, क्योंकि आपके तरीके की कोई अन्य प्रक्रिया नहीं है, यह काफी हद तक बेमानी है (सिवाय इनकैप्सुलेशन के!), इसलिए doactualStuffOnObject(p_jsonObject);बूलियन वापस आ सकता है!


1

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

ऐसा कई बार हो सकता है कि आप जो अपवाद कर रहे हैं, उससे कॉलर को कोई मतलब नहीं होगा (यानी यह एक नेटवर्क अपवाद है), जिस स्थिति में आपको इसे डोमेन विशिष्ट अपवाद में लपेटना चाहिए।

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


1

यदि आप अपने उदाहरण में कोड पैटर्न का उपयोग करने जा रहे हैं, तो इसे TryDoSomething कहते हैं, और केवल विशिष्ट अपवादों को पकड़ते हैं।

नैदानिक ​​उद्देश्यों के लिए अपवादों को लॉग करते समय एक अपवाद फ़िल्टर का उपयोग करने पर भी विचार करें । VB में एक्सेप्शन फिल्टर के लिए भाषा समर्थन है। ग्रीगम के ब्लॉग के लिंक में एक कार्यान्वयन है जिसे C # से उपयोग किया जा सकता है। एक्सेप्शन फिल्टर में कैच और रीथ्रो से अधिक डिबगैबिलिटी के लिए बेहतर गुण होते हैं। विशेष रूप से आप फ़िल्टर में समस्या को लॉग इन कर सकते हैं और अपवाद को प्रचारित करना जारी रख सकते हैं। यह विधि एक JIT (बस समय में) डिबगर संलग्न करने के लिए पूर्ण मूल ढेर की अनुमति देता है। एक पुनर्खरीद उस बिंदु पर स्टैक को काट देता है जिसे इसे फिर से उखाड़ दिया गया था।

ऐसे मामले जहां TryXXXX समझ में आता है, जब आप किसी थर्ड पार्टी फंक्शन को रैप कर रहे होते हैं, जो उन मामलों में फेंकता है जो वास्तव में असाधारण नहीं हैं, या फ़ंक्शन को कॉल किए बिना टेस्ट करना आसान है। एक उदाहरण कुछ इस तरह होगा:

// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse); 

bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
     try
     {
         parsedInt = ParseHexidecimal(numberToParse);
         return true;
     }
     catch(NumberNotHexidecimalException ex)
     {
         parsedInt = 0;
         return false;
     }
     catch(Exception ex)
     {
         // Implement the error policy for unexpected exceptions:
         // log a callstack, assert if a debugger is attached etc.
         LogRetailAssert(ex);
         // rethrow the exception
         // The downside is that a JIT debugger will have the next
         // line as the place that threw the exception, rather than
         // the original location further down the stack.
         throw;
         // A better practice is to use an exception filter here.
         // see the link to Exception Filter Inject above
         // http://code.msdn.microsoft.com/ExceptionFilterInjct
     }
}

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


मुझे .net में TryXXX पैटर्न पसंद है।
जोशबर्के

1

मैं सुझाव देता हूं कि आप जिस भाषा का उपयोग कर रहे हैं, उसके लिए मानक पुस्तकालय से अपने संकेत ले सकते हैं। मैं C # के लिए नहीं बोल सकता, लेकिन जावा को देखते हैं।

उदाहरण के लिए java.lang.reflect.Array में एक स्थिर setविधि है:

static void set(Object array, int index, Object value);

सी तरीका होगा

static int set(Object array, int index, Object value);

... वापसी मूल्य के साथ एक सफलता सूचक है। लेकिन आप सी दुनिया में नहीं हैं।

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

जैसा कि अन्य ने उल्लेख किया है - आप जिस तरह के अपवाद को पकड़ते हैं, उसमें आपको यथासंभव विशिष्ट होना चाहिए।


यह एक बहुत ही मान्य टिप्पणी है, भाषा के प्रति सम्मानजनक हो और यह पारंपरिक रूप से इस तरह के मुद्दों का प्रबंधन करता है। एक जावा दुनिया में एक सी मानसिकता मत लाओ।
अटारीपते

0

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

यदि यह एक ऐसा उत्पाद है जिसे आप लॉन्च करेंगे, तो आपको उन अपवादों को कहीं लॉग करना चाहिए, यह आपको भविष्य में चीजों को ट्यून करने में मदद करेगा।

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


यह मत भूलो कि एक अपवाद ब्लॉक की स्थापना की लागत भी ...
devstuff

0

मेरी रणनीति:

यदि मूल फ़ंक्शन शून्य वापस आ गया है तो मैं इसे वापस बूल में बदल सकता हूं । अपवाद / त्रुटि वापसी हुई है तो गलत है, अगर सब कुछ ठीक वापसी थी सच

यदि फ़ंक्शन को कुछ वापस करना चाहिए तो जब अपवाद / त्रुटि वापस शून्य हो गई , अन्यथा वापसी योग्य आइटम।

बूल के बजाय एक स्ट्रिंग त्रुटि के विवरण से युक्त हो सकता है।

कुछ भी वापस करने से पहले हर मामले में त्रुटि लॉग करें।


0

कुछ बेहतरीन जवाब यहाँ। मैं यह जोड़ना चाहूंगा, कि यदि आप पोस्ट की गई चीज़ों को समाप्त करते हैं, तो स्टैक ट्रेस की तुलना में कम से कम प्रिंट करें। कहो कि तुम उस समय क्या कर रहे थे, और Ex.getMessage (), डेवलपर को एक मौका देने के लिए।


मैं पूरी तरह से सहमत हूँ। मैंने केवल Ex.printStackTrace () किया था; एक ऐसी चीज़ के उदाहरण के रूप में जो मैं पकड़ में कर रहा था (यानी पुनर्विचार नहीं)।
अटारीपत्ते

0

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

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

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

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

इन दो प्रकार के एरर हैंडलिंग के अलावा, बीच के बाकी कोड के सभी कोड और त्रुटि ऑब्जेक्ट्स को आज़माने / पकड़ने के लिए स्वतंत्र और स्पष्ट होना चाहिए। इस तरह, यह बस और जैसा कि आप इसका उपयोग करते हैं, या आप इसके साथ क्या करते हैं, कोई उम्मीद नहीं है।

पॉल।


0

मुझे उत्तर के साथ थोड़ा देर हो सकती है लेकिन त्रुटि से निपटने कुछ ऐसा है जिसे हम हमेशा बदल सकते हैं और समय के साथ विकसित हो सकते हैं। अगर आप इस विषय में कुछ और पढ़ना चाहते हैं तो मैंने अपने नए ब्लॉग में इसके बारे में एक पोस्ट लिखी है। http://taoofdevelopment.wordpress.com

खुश कोडिंग।

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