एप्लिकेशन को क्रैश से रोकने के लिए / पकड़ का उपयोग करना


79

मैं एक एंड्रॉइड ऐप पर काम कर रहा हूं जो उपयोग करता है try/catch अक्सर ऐसे स्थानों पर दुर्घटनाग्रस्त होने से बचाने के लिए जहां कोई आवश्यकता नहीं है। उदाहरण के लिए,

इसके xml layoutसाथ एक दृश्य id = toolbarसंदर्भित है:

// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
    View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}

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

मैंने अपने सीनियर से उसे समझाने के लिए कहा और उसने कहा,

यह उत्पादन में दुर्घटना को रोकने के लिए है।

मैं इससे पूरी तरह असहमत हूं । मेरे लिए यह क्रैश से ऐप्स को रोकने का तरीका नहीं है। यह उस डेवलपर को दिखाता है को पता नहीं है कि वह क्या कर रहा है और वह संदेह में है।

क्या एंटरप्राइज़ ऐप्स को क्रैश से रोकने के लिए उद्योग में इसका उपयोग किया जा रहा है?

अगर try/catch वास्तव में, वास्तव में हमारी आवश्यकता है तो क्या यूआई थ्रेड या अन्य थ्रेड्स के साथ एक अपवाद हैंडलर संलग्न करना और वहां सब कुछ पकड़ना संभव है? यदि संभव हो तो यह एक बेहतर तरीका होगा।

हां, खाली try/catchखराब है और अगर हम सर्वर पर स्टैक ट्रेस या लॉग अपवाद को प्रिंट करते हैं, तो try/catchसभी एप्लिकेशन में यादृच्छिक रूप से कोड के ब्लॉक लपेटने से मुझे कोई मतलब नहीं है जैसे कि जब प्रत्येक फ़ंक्शन एक में संलग्न है try/catch

अपडेट करें

जैसा कि इस प्रश्न पर बहुत ध्यान दिया गया है और कुछ लोगों ने इस प्रश्न का गलत अर्थ निकाला है (शायद इसलिए कि मैंने इसे स्पष्ट रूप से प्रकाशित नहीं किया है) मैं इसे फिर से समझने जा रहा हूं।

यहाँ डेवलपर्स क्या कर रहे हैं

  • एक फ़ंक्शन लिखित और परीक्षण किया जाता है , यह एक छोटा सा फ़ंक्शन हो सकता है जो केवल विचारों या एक जटिल को शुरू करता है, परीक्षण के बाद इसे try/catchब्लॉक के चारों ओर लपेटा जाता है। यहां तक ​​कि फ़ंक्शन के लिए जो कभी भी कोई अपवाद नहीं फेंकेंगे।

  • इस अभ्यास का उपयोग पूरे अनुप्रयोग में किया जाता है। कुछ समय स्टैक ट्रेस मुद्रित किया जाता है और कभी-कभी debug logकुछ यादृच्छिक त्रुटि संदेश के साथ। यह त्रुटि संदेश डेवलपर से डेवलपर तक भिन्न होता है।

  • इस दृष्टिकोण के साथ, ऐप क्रैश नहीं करता है लेकिन ऐप का व्यवहार अनिर्धारित हो जाता है। यहां तक ​​कि कुछ समय के लिए यह पालन करना कठिन है कि क्या गलत हुआ।

  • मैं जो वास्तविक प्रश्न पूछ रहा हूं, वह था; क्या यह उद्योग में दुर्घटनाओं से होने वाले उद्यम अनुप्रयोगों को रोकने के लिए पालन किया जा रहा है? और मैं खाली कोशिश / कैच के बारे में नहीं पूछ रहा हूं । क्या यह पसंद है, उपयोगकर्ताओं को एप्लिकेशन से प्यार है जो उन अनुप्रयोगों से दुर्घटना नहीं करता है जो अप्रत्याशित रूप से व्यवहार करते हैं? क्योंकि यह वास्तव में इसे या तो क्रैश करने के लिए उकसाता है या उपयोगकर्ता को रिक्त स्क्रीन के साथ पेश करता है या व्यवहार उपयोगकर्ता इससे अनजान है।

  • मैं यहाँ वास्तविक कोड से कुछ स्निपेट पोस्ट कर रहा हूँ

      private void makeRequestForForgetPassword() {
        try {
            HashMap<String, Object> params = new HashMap<>();
    
            String email= CurrentUserData.msisdn;
            params.put("email", "blabla");
            params.put("new_password", password);
    
            NetworkProcess networkProcessForgetStep = new NetworkProcess(
                serviceCallListenerForgotPasswordStep, ForgotPassword.this);
            networkProcessForgetStep.serviceProcessing(params, 
                Constants.API_FORGOT_PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
     private void languagePopUpDialog(View view) {
        try {
            PopupWindow popupwindow_obj = popupDisplay();
            popupwindow_obj.showAsDropDown(view, -50, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    void reloadActivity() {
        try {
            onCreateProcess();
        } catch (Exception e) {
        }
    }
    

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


11
आपके सवाल का जवाब नहीं, लेकिन कभी भी अपवादों को न निगलें catch(Exception e){}- इस टिप्पणी ने सवाल को संपादित करने से पहले समझ में आया
डरावना


29
आह, बदनामON ERROR RESUME NEXT
Deduplicator

टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
भार्गव राव

1
इस सवाल ने मुझे सोचने पर मजबूर कर दिया, क्योंकि मैं भी कोशिश करता हूं {} कैच (अपवाद e) {} कई बार जब मैं समय से बाहर चल रहा होता हूं
राउत डारपॉन

जवाबों:


81

बेशक, हमेशा नियमों के अपवाद होते हैं, लेकिन अगर आपको अंगूठे के नियम की आवश्यकता है - तो आप सही हैं; खाली पकड़ ब्लॉक "बिल्कुल" बुरा अभ्यास है।

आइए एक नज़दीकी नज़र डालें, पहले अपने विशिष्ट उदाहरण से शुरू करते हैं:

try {
  View view = findViewById(R.id.toolbar);
}
catch(Exception e) { }

तो, कुछ के लिए एक संदर्भ बनाया जाता है; और जब वह विफल होता है ... तो कोई बात नहीं; क्योंकि उस संदर्भ का उपयोग पहली जगह में नहीं किया गया है! उपरोक्त कोड बिल्कुल बेकार लाइन शोर है । या उस कोड को लिखने वाले व्यक्ति को शुरू में यह लगता है कि एक दूसरी, इसी तरह की कॉल जादुई रूप से एक अपवाद नहीं फेंकती है ?!

शायद यह देखने के लिए था:

try {
  View view = findViewById(R.id.toolbar);
  ... and now do something with that view variable ...
}
catch(Exception e) { }

लेकिन फिर, यह क्या मदद करता है ?! अपवाद के लिए मौजूद संवाद क्रमशः प्रचार अपने कोड के भीतर त्रुटि स्थितियों। त्रुटियों को अनदेखा करना शायद ही कभी एक अच्छा विचार है। वास्तव में, एक अपवाद का इलाज किया जा सकता है जैसे:

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

लंबी कहानी छोटी: न्यूनतम चीज जो आप एक अपवाद के साथ करते हैं, उसे लॉग / ट्रेस करना है; ताकि जब आप बाद में आते हैं, तो आप कुछ समस्या को समझें "ठीक है, इस बिंदु पर उस समय अपवाद हुआ"।

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

अंत में, वार्ड कनिंघम को उद्धृत करें :

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

उस में डूबने दो और उसके बारे में ध्यान करो। स्वच्छ कोड आपको आश्चर्यचकित नहीं करता है । जो उदाहरण आप हमें दिखा रहे हैं वह हर किसी को आश्चर्यचकित करता है ।

अद्यतन , ओपी के बारे में पूछने वाले अद्यतन के बारे में

try {
  do something
}
catch(Exception e) { 
  print stacktrace
}

एक ही उत्तर: "सभी जगह" करना भी बुरा व्यवहार है। क्योंकि यह कोड पाठक को आश्चर्यचकित भी करता है।

उपरोक्त:

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

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


1
यदि मैं स्टैक ट्रेस प्रिंट करता हूं तो क्या होगा? मुझे अभी भी नहीं लगता कि मुझे यहाँ कोशिश / पकड़ने की ज़रूरत है।
मल्लाउद्दीन

3
मुझे मानना ​​पड़ेगा कि मुझे आपका संपादन नहीं करना है। एक वास्तविक विचार नहीं है कि आप वहां क्या कर रहे हैं; या जहाँ आप इस के साथ हो रहे हैं।
घोस्टकट

@mallaudin प्रोग्राम को क्रैश करने वाली लाइन के बाद एक सामान्य मामले में कुछ भी निष्पादित नहीं किया जाएगा (obvs), इसलिए मुद्रण केवल बकवास है। इस विशिष्ट मामले में अर्थात + को छोड़कर, कम से कम कुछ दिखाएगा और अपवाद को चुप नहीं किया जाएगा।
पीटर बैडिडा

2
@GhostCat ओपी एक अन्य जवाब में एक टिप्पणी पर कहता है कि अपवाद ब्लॉकों में पहले से ही लॉगिंग कॉल हैं। यह सवाल गलत है कि वास्तव में क्या चल रहा है, इसलिए मुझे नहीं लगता कि वरिष्ठ देव पर अक्षम होने का आरोप लगाना यहाँ मददगार है। मुझे लगता है कि ओपी हमें जो दे रहा है, उससे कहीं अधिक चल रहा है।
jpmc26

1
@GhostCat यह रेपो के बारे में नहीं है, मुझे सिर्फ यह महसूस हुआ कि मेरा उदाहरण खराब था। सभी ने सोचा कि मैं खाली कोशिश / पकड़ के
मल्लाउद्दीन

15

से Android दस्तावेज़ :

आइए इसे निम्न के रूप में देखें -

कैच जेनेरिक एक्सेप्शन

अपवादों को पकड़ने के दौरान आलसी होना भी ललचा सकता है और ऐसा कुछ करना चाहिए:

try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}

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

यह आपके कोड की विफलता से निपटने के गुणों को अस्पष्ट करता है, जिसका अर्थ है कि यदि कोई Exceptionआपके द्वारा कॉल किए जा रहे कोड में एक नया प्रकार जोड़ता है , तो संकलक आपको यह महसूस करने में मदद नहीं करेगा कि आपको त्रुटि को अलग तरीके से संभालने की आवश्यकता है

सामान्य अपवाद को पकड़ने के लिए विकल्प:

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

ज्यादातर मामलों में आपको अलग-अलग प्रकार के अपवाद को उसी तरह से हैंडल नहीं करना चाहिए।

इस उत्तर के लिए स्रोत से थोड़ा संशोधित स्वरूपण / परिच्छेद।

PS अपवादों से डरो मत !! वे मित्र हैं!!!


1
यदि आप व्यक्तिगत रूप से प्रत्येक अपवाद को पकड़ते हैं, तो अनिश्चित स्थिति में निष्पादन को जारी रखने से बचें (जैसी चीजों से बचें Object a; try { a = thing(); } catch (Exception e) {...} try { a.action(); } catch (Exception e) {...})
njzk2

निष्पक्ष होना, जेनेरिक Exceptionको पकड़ना "लॉग-पहले-दुर्घटनाग्रस्त" प्रणाली के हिस्से के रूप में उपयोगी हो सकता है, हालांकि इसे उस मामले में पुनर्विचार करना चाहिए।
जस्टिन टाइम - मोनिका

9

मैं इसे कुछ अन्य उत्तर के लिए एक टिप्पणी के रूप में रखूंगा, लेकिन मेरे पास अभी तक इसके लिए प्रतिष्ठा नहीं है।

आप यह कहने में सही हैं कि यह बुरा अभ्यास है, वास्तव में आपने जो पोस्ट किया है वह अपवादों के संबंध में विभिन्न प्रकार के बुरे अभ्यास को दर्शाता है।

  1. त्रुटि से निपटने में कमी
  2. जेनेरिक कैच
  3. कोई जानबूझकर अपवाद नहीं
  4. कंबल कोशिश / पकड़

मैं इस उदाहरण के माध्यम से उन सभी को समझाने की कोशिश करूँगा।

try {
   User user = loadUserFromWeb();     
   if(user.getCountry().equals("us")) {  
       enableExtraFields();
   }
   fillFields(user);   
} catch (Exception e) { 
}

यह कई मायनों में विफल हो सकता है जिसे अलग तरीके से संभाला जाना चाहिए।

  1. खेतों को भरा नहीं जाएगा, इसलिए उपयोगकर्ता को खाली स्क्रीन के साथ प्रस्तुत किया जाता है और फिर ... क्या? कुछ भी नहीं - त्रुटि से निपटने की कमी।
  2. विभिन्न प्रकार की त्रुटियों के बीच कोई अंतर नहीं है, उदाहरण के लिए इंटरनेट समस्याएं या सर्वर के साथ समस्याएं (आउटेज, टूटा हुआ अनुरोध, दूषित संचरण, ...) - जेनेरिक कैच।
  3. आप अपने स्वयं के उद्देश्यों के लिए अपवादों का उपयोग नहीं कर सकते क्योंकि वर्तमान प्रणाली उसी के साथ हस्तक्षेप करती है। - कोई जानबूझकर अपवाद नहीं
  4. अनावश्यक और अप्रत्याशित त्रुटियां (जैसे null.equals (...)) आवश्यक कोड को निष्पादित नहीं कर सकती हैं। - कंबल कोशिश / पकड़

समाधान

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

(4) यदि उपयोगकर्ता अधूरा है, उदाहरण के लिए देश ज्ञात नहीं है और अशक्त है। बराबर पद्धति एक NullPointerException बनाएगी। अगर वह एनपीई सिर्फ ऊपर की तरह फेंका और पकड़ा जाता है, तो फिलफिल्ड्स (उपयोगकर्ता) विधि को नहीं बुलाया जाएगा, भले ही इसे अभी भी समस्याओं के बिना निष्पादित किया जा सकता है। आप इसे शून्य चेक, निष्पादन आदेश बदलने, या कोशिश / कैच स्कोप को समायोजित करने से रोक सकते हैं। (या आप इस तरह कोडिंग को बचा सकते हैं: "हमें"। असमान (user.getCountry ()), लेकिन मुझे एक उदाहरण प्रदान करना था)। बेशक किसी भी अन्य अपवाद से fillFields () को निष्पादित होने से रोका जा सकेगा, लेकिन अगर कोई उपयोगकर्ता नहीं है, तो आप शायद इसे वैसे भी निष्पादित नहीं करना चाहते हैं।

(1, 2, 3) वेब से लोड हो रहा है अक्सर IOException से HttpMessageNotReadable अपवाद को छोड़कर सिर्फ वापस करने के लिए, अपवादों की एक किस्म फेंकता है। हो सकता है कि उपयोगकर्ता इंटरनेट से जुड़ा नहीं है, ऐसा हो सकता है कि बैकएंड सर्वर में कोई बदलाव हुआ था या यह डाउन हो गया है, लेकिन आपको नहीं पता है क्योंकि आप कैच (अपवाद) करते हैं - इसके बजाय आपको विशिष्ट अपवादों को पकड़ना चाहिए। आप उनमें से कई को इस तरह से पकड़ भी सकते हैं

try{
   User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist
   if(user == null) { 
       throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used.
   }
   fillFields(user);
   if("us".equals(user.getCountry()) {
       enableExtraFields();
   }
} catch(NoInternetException e){
    displayWarning("Your internet conneciton is down :(");
} catch(ServerNotAvailableException e){
    displayWarning("Seems like our server is having trouble, try again later.");
} catch(UserDoesNotExistException e){
    startCreateUserActivity();
}

मुझे आशा है कि यह समझाता है।

कम से कम एक त्वरित सुधार के रूप में, आप जो कर सकते थे, वह अपवाद के साथ आपके बैकएंड पर एक घटना भेज सकता है। उदाहरण के लिए फायरबेस या क्रैशलीटिक्स के माध्यम से। इस तरह आप कम से कम सामान देख सकते हैं जैसे (हे, मुख्य गतिविधि हमारे उपयोगकर्ताओं के 80% के लिए लोड नहीं होती है जैसे (4) की समस्या के कारण।


8

यह निश्चित रूप से एक बुरा प्रोग्रामिंग अभ्यास है।

वर्तमान परिदृश्य से, यदि सैकड़ों हैं try catch इस तरह के , तो आपको यह भी पता नहीं चलेगा कि एप्लिकेशन को डिबग किए बिना अपवाद कहां होता है, जो कि एक बुरा सपना है यदि आपका एप्लिकेशन उत्पादन वातावरण में है।

लेकिन आप एक लकड़हारा शामिल कर सकते हैं ताकि आपको पता चले कि जब एक अपवाद फेंकता है (और क्यों)। यह आपके सामान्य वर्कफ़्लो को नहीं बदलेगा।

...
try {
    View view = findViewById(R.id.toolbar);
}catch(Exception e){
    logger.log(Level.SEVERE, "an exception was thrown", e);
}
...

7

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

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

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

[अब कुछ मामले ऐसे हैं जहाँ खाली हैं catch es ठीक हैं। उदाहरण के लिए, लॉगिंग एक ऐसी चीज है जिसे आप एक खाली पकड़ में लपेटने को सही ठहरा सकते हैं। यदि लॉगिंग में से कुछ भी नहीं लिखा जा सकता है तो भी आपका आवेदन संभवतः ठीक चलेगा लेकिन वे विशेष मामले हैं जिन्हें आपको सामान्य ऐप में खोजने के लिए वास्तव में कड़ी मेहनत करनी होगी।]

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


3

यह कई कारणों से खराब है:

  1. तुम क्या कर रहे हो कि findViewByIdएक अपवाद फेंकता है? इसे ठीक करें (और मुझे बताएं, क्योंकि मैंने इसे कभी नहीं देखा है) पकड़ने के बजाय।
  2. Exceptionजब आप एक विशेष प्रकार के अपवाद को पकड़ सकते हैं, तो उसे न पकड़ें ।
  3. यह धारणा है कि अच्छे ऐप क्रैश नहीं होते हैं। यह सच नहीं है। एक अच्छा ऐप क्रैश हो जाता है अगर यह होना चाहिए।

यदि कोई ऐप खराब स्थिति में चला जाता है, तो उसके लिए दुर्घटनाग्रस्त हो जाना बेहतर होता है क्योंकि वह अपनी अनुपयोगी अवस्था में घूमता है। जब कोई NPE देखता है, तो किसी को केवल एक अशक्त जांच में नहीं रहना चाहिए और न ही चलना चाहिए। बेहतर तरीका यह पता लगाना है कि क्यों कुछ अशक्त है और या तो इसे अशक्त होने से रोकें, या (यदि अशक्त एक वैध और अपेक्षित राज्य होने के नाते समाप्त होता है) अशक्त के लिए जाँच करें। लेकिन आपको यह समझना होगा कि समस्या पहले स्थान पर क्यों होती है।


2

मैं पिछले 4-5 वर्षों से एंड्रॉइड ऐप्स विकसित कर रहा हूं और कभी भी दृश्य आरंभ के लिए एक कोशिश पकड़ने का उपयोग नहीं किया है।

अगर इसका टूलबार इस तरह का है

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

उदाहरण: - एक दृश्य से एक पाठ दृश्य पाने के लिए (टुकड़ा / संवाद / किसी भी कस्टम दृश्य)

TextView textview = (TextView) view.findViewById(R.id.viewId);

TextView textview = (TextView) view.findViewById (R.id.viewId);

इसके अलावा

View view = findViewById(R.id.toolbar);

एक दृश्य वस्तु की वास्तविक दृश्य प्रकार की तुलना में न्यूनतम पहुंच होती है।

नोट: - यह दृश्य लोड होने के कारण दुर्घटनाग्रस्त हो सकता है। लेकिन ट्राई कैच को जोड़ना एक बुरा अभ्यास है।


कई मामलों में दृश्य डालना आवश्यक नहीं है। कुछ तरीके हैं जो आपके पास हैं Viewजो पहले से ही उपयोगी (जैसे setVisibility()) हो सकते हैं , आपके बिना यह निर्दिष्ट किए बिना कि किस वर्ग का उपयोग किया जाता है। (उदाहरण के लिए, एक लेआउट के मामले में, जिसे समय-समय पर बदलने की संभावना है)
njzk2

1

हां, ऐप को क्रैश होने से बचाने के लिए ट्राइ / कैच का उपयोग किया जाता है लेकिन आपको अपने प्रश्न में दर्शाए अनुसार XML से दृश्य प्राप्त करने के लिए ट्राइ / कैच की आवश्यकता नहीं है।

कोशिश / कैच का उपयोग आमतौर पर किसी भी http अनुरोध को करते समय किया जाता है, जबकि किसी भी स्ट्रिंग को URL पर पार्स करने, URL कनेक्शन बनाने आदि के लिए और स्टैक ट्रेस प्रिंट करने के लिए भी सुनिश्चित करें। नहीं मुद्रण यह कोशिश / पकड़ने के साथ आसपास में बहुत मतलब नहीं है।


1

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

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

एक केंद्रीय अपवाद हैंडलिंग / लॉगिंग / रिपोर्टिंग और नियंत्रित शटडाउन होने के बाद, स्थानीय अपवादों को यथासंभव पकड़ने के लिए अपवाद हैंडलिंग को फिर से लिखना शुरू करें। कोशिश करें कि {} ब्लॉक को यथासंभव छोटा करें।


1

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

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

अब, जब आप अपने लिए कोई ऐप विकसित नहीं कर रहे हैं, लेकिन किसी कंपनी या निगम के लिए, इस विषय पर अतिरिक्त आवश्यकताओं का सामना करना आम है:

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

तो, संक्षिप्त उत्तर यह है कि आपने जो कोड पाया है वह एक अच्छा अभ्यास उदाहरण नहीं है, क्योंकि यह ऐप की गुणवत्ता में सुधार के बिना बनाए रखना कठिन और महंगा है।


1

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

तो सवाल:

है

try{
  someMethod();
}catch(Exception e){}

अच्छा अभ्यास? नहीं! यहाँ कुछ बिंदु हैं:

  1. सबसे महत्वपूर्ण बात: यह एक खराब ग्राहक अनुभव है। मुझे कैसे पता चलेगा कि कुछ बुरा हो रहा है? मेरे ग्राहक मेरे ऐप का उपयोग करने की कोशिश कर रहे हैं और कुछ भी काम नहीं कर रहा है। वे अपने बैंक खाते की जांच नहीं कर सकते, अपने बिलों का भुगतान करें, जो भी मेरा ऐप करता है। मेरा ऐप पूरी तरह से बेकार है, लेकिन हे, कम से कम यह दुर्घटना नहीं हुई! (मेरे हिस्से का मानना ​​है कि यह "सीनियर" देव को कम दुर्घटना संख्या के लिए ब्राउनी अंक मिलता है, इसलिए वे सिस्टम को गेमिंग कर रहे हैं।)

  2. जब मैं विकास कर रहा होता हूं और मैं खराब कोड लिखता हूं, अगर मैं सिर्फ ऊपरी परत पर सभी अपवादों को पकड़ रहा हूं और निगल रहा हूं तो मेरे पास कोई लॉगिंग नहीं है। मेरे कंसोल में कुछ भी नहीं है, और मेरा ऐप चुपचाप विफल रहता है। मैं जो बता सकता हूं, उससे सब ठीक लगता है। इसलिए मैं कोड देता हूं ... मेरा DAO ऑब्जेक्ट पूरे समय के लिए बंद था, और ग्राहक के भुगतान वास्तव में DB में कभी भी अपडेट नहीं हो रहे थे। वूप्स! लेकिन मेरा ऐप क्रैश नहीं हुआ, इसलिए यह प्लस है।

  3. शैतान के वकील की भूमिका निभाते हुए, कहते हैं कि मैं हर अपवाद को पकड़ने और निगलने के साथ ठीक था। यह बहुत आसान एंड्रॉयड में एक कस्टम अपवाद संचालक लिखने के लिए। आप वास्तव में सिर्फ अगर है हर अपवाद को पकड़ने के लिए, आप इसे एक ही स्थान पर और नहीं काली मिर्च में कर सकते हैं try/catchअपने सभी codebase से अधिक।

मैंने पिछले दिनों जिन डेवलपर्स के साथ काम किया है उनमें से कुछ ने सोचा कि दुर्घटनाग्रस्त होना बुरा था।

मुझे उन्हें आश्वस्त करना होगा कि हम चाहते हैं कि हमारा ऐप क्रैश हो जाए। नहीं, एक अस्थिर ऐप ठीक नहीं है, लेकिन क्रैश का मतलब है कि हमने कुछ गलत किया है और हमें इसे ठीक करने की आवश्यकता है। जितनी तेजी से यह दुर्घटनाग्रस्त होती है, पहले हम इसे ढूंढते हैं, इसे ठीक करना उतना ही आसान है। एकमात्र अन्य विकल्प जिसके बारे में मैं सोच सकता हूं कि उपयोगकर्ता को एक टूटे हुए सत्र में जारी रखने की अनुमति है, जिसे मैं अपने उपयोगकर्ताबेस को बंद करने के साथ बराबर करता हूं।


0

यह उपयोग करने के लिए बुरा अभ्यास है catch(Exception e){}क्योंकि आप अनिवार्य रूप से त्रुटि की अनदेखी कर रहे हैं। आप शायद जो करना चाहते हैं वह कुछ और है:

try {
    //run code that could crash here
} catch (Exception e) {
    System.out.println(e.getMessage());
}

0

हम आपके उसी तर्क का बहुत उपयोग करते हैं। उपयोगtry-catchप्रोडक्शन ऐप्स को क्रैश होने से बचाने के लिए ।

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

हम Crashlyticsअपवादों को लॉग करने के लिए उपयोग करते हैं। कोड क्रैश नहीं होगा (लेकिन कुछ कार्यक्षमता बाधित हो जाएगी)। लेकिन आपको इसके डैशबोर्ड में अपवाद लॉग मिलता है Fabric/Crashlytics। आप इन लॉग को देख सकते हैं और अपवादों को ठीक कर सकते हैं।

try {
    codeThatCouldRaiseError();
} catch (Exception e) {
    e.printStackTrace();
    Crashlytics.logException(e);
}

हाँ। यही लोग यहां कर रहे हैं लेकिन मैं इससे असहमत हूं। इसलिए मैंने सवाल पोस्ट किया। क्या आप कुछ और तार्किक लेकर आ सकते हैं?
मलैडिन

4
@mallaudin उदाहरण कोड को पोस्ट न करें जो आपके बारे में पूछ रहे कोड को गलत तरीके से प्रस्तुत करता है। यह आपके द्वारा प्राप्त उत्तर को बहुत बदल सकता है
jpmc26

@ jpmc26 हाँ। मैंने देखा है कि जवाब में।
मालौदीन

0

जबकि मैं अन्य प्रतिक्रियाओं से सहमत हूं, एक ऐसी परिस्थिति है जिसका मैंने बार-बार सामना किया है जहां यह रूपांतर थोड़ा सहन करने योग्य है। मान लीजिए कि किसी वर्ग के लिए किसी ने इस तरह का कोड लिखा है:

private int foo=0;

    . . .

public int getFoo() throws SomeException { return foo; }

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

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