आज़माएँ / कैच / लॉग / रेथ्रो - क्या एंटी पैटर्न है?


19

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

public static bool DoOperation(int num1, int num2)
{
    try
    {
        /* do some work with num1 and num2 */
    }
    catch (Exception ex)
    {
        logger.log("error occured while number 1 = {num1} and number 2 = {num2}"); 
        throw;
    }
}

क्या अच्छा अभ्यास संभालते हुए अपवाद को बनाए रखते हुए इसे प्राप्त करने का सही तरीका है? मैंने इसके लिए PostSharp की तरह AOP फ्रेमवर्क के बारे में सुना लेकिन यह जानना चाहूंगा कि क्या इन AOP फ्रेमवर्क से जुड़ी कोई नकारात्मक या बड़ी प्रदर्शन लागत है।

धन्यवाद!


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

मैं कह रहा हूं कि प्रत्येक विधि को आज़माएं / पकड़ें और बस पकड़ ब्लॉक और रीथ्रो में लॉग इन करें - क्या यह करना ठीक है?
rahulaga_dev

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

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

1
Liath: छोटे कोड स्निपेट जोड़े गए। मैं
बजे

जवाबों:


19

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

यहां विचार आपके आवेदन को डीबग करने की क्षमता बढ़ाने के लिए है।

उदाहरण # 1: इसे संभालें

try
{
    doSomething();
}
catch (Exception e)
{
    log.Info("Couldn't do something", e);
    doSomethingElse();
}

यदि आप अपवाद को संभालते हैं, तो आप आसानी से अपवाद लॉग प्रविष्टि के महत्व को डाउनग्रेड कर सकते हैं और श्रृंखला को छोड़कर उस अपवाद को समाप्त करने का कोई कारण नहीं है। यह पहले से ही निपटा है।

एक अपवाद को संभालने में उपयोगकर्ताओं को सूचित करना शामिल हो सकता है कि एक समस्या हुई, घटना को लॉग करना, या बस इसे अनदेखा करना।

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

try
{
    context.DrawLine(x1,y1, x2,y2);
}
catch (OutOfMemoryException)
{
    // WinForms throws OutOfMemory if the figure you are attempting to
    // draw takes up less than one pixel (true story)
}

उदाहरण # 2: अतिरिक्त संदर्भ जोड़ें और फेंकें

try
{
    doSomething(line);
}
catch (Exception e)
{
    throw new MyApplicationException(filename, line, e);
}

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

उदाहरण # 3: अपवाद के साथ कुछ मत करो

try
{
    doSomething();
}
finally
{
   // cleanup resources but let the exception percolate
}

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


मुझे पसंद आया " समस्या स्थानीय कैच ब्लॉक नहीं है, समस्या लॉग और रीथ्रो है " मुझे लगता है कि क्लीनर लॉगिंग सुनिश्चित करने के लिए यह सही समझ में आता है। लेकिन आखिरकार इसका मतलब यह है कि सभी तरीकों में बिखरे हुए / पकड़ने के प्रयास के साथ ठीक है, है ना? मुझे लगता है कि यह सुनिश्चित करने के लिए कुछ दिशा-निर्देश होना चाहिए कि ऐसा करने के हर तरीके के बजाय इस प्रथा का विवेकपूर्ण तरीके से पालन किया जाए।
rahulaga_dev 3

मैंने अपने उत्तर में एक दिशानिर्देश प्रदान किया। क्या यह आपके सवालों का जवाब नहीं देता है?
बेरिन लोरिट्श

@rahulaga_dev मुझे नहीं लगता कि कोई दिशानिर्देश / चांदी की गोली है इसलिए इस मुद्दे को हल करें, क्योंकि यह संदर्भ पर बहुत निर्भर करता है। एक सामान्य दिशानिर्देश नहीं हो सकता है जो आपको बताता है कि अपवाद को कहां से संभालना है या कब इसे फिर से फेंकना है। IMO, जो एकमात्र दिशानिर्देश मैं देख रहा हूं वह है लॉगिंग / हैंडलिंग को नवीनतम संभव समय से हटाना और पुन: प्रयोज्य कोड में लॉगिंग से बचने के लिए, जैसे कि आप अनावश्यक निर्भरता पैदा न करें। यदि आपने उन्हें अपने तरीके से संभालने का अवसर दिए बिना चीजों को लॉग किया है (यानी अपवादों को संभाला) तो आपके कोड के उपयोगकर्ता भी बहुत खुश नहीं होंगे। बस मेरे दो सेंट :)
andreee

7

मुझे विश्वास नहीं है कि स्थानीय कैच एक एंटी-पैटर्न हैं, वास्तव में अगर मुझे सही ढंग से याद है कि यह वास्तव में जावा में लागू है!

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

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

  • प्रासंगिक जानकारी जोड़ें (जैसे कि वस्तुओं की स्थिति या क्या चल रहा था)
  • अपवाद को सुरक्षित रूप से संभालें (जैसे कि ट्रायक्स विधि)
  • आपका सिस्टम एक सेवा सीमा पार कर रहा है और बाहरी लाइब्रेरी या एपीआई में कॉल कर रहा है
  • आप एक अलग प्रकार के अपवाद को पकड़ना और हटाना चाहते हैं (शायद मूल अपवाद के रूप में आंतरिक अपवाद के साथ)
  • अपवाद को कुछ कम मूल्य पृष्ठभूमि की कार्यक्षमता के हिस्से के रूप में फेंक दिया गया था

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

उदाहरण के लिए:

public bool TryConnectToDatabase()
{
  try
  {
    this.ConnectToDatabase(_databaseType); // this method will throw if it fails to connect
    return true;
  }
  catch(Exception ex)
  {
     this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
    return false;
  }
}

या एक पुनर्खरीद उदाहरण:

public IDbConnection ConnectToDatabase()
{
  try
  {
    // connect to the database and return the connection, will throw if the connection cannot be made
  }
  catch(Exception ex)
  {
     this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
    throw;
  }
}

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

जो भी दृष्टिकोण आप लेते हैं वह हमेशा इस परिदृश्य के लिए इकाई परीक्षण बनाने के लायक है ताकि आप यह सुनिश्चित कर सकें कि कार्यक्षमता बाद में तारीख में परियोजना के प्रवाह को परिवर्तित नहीं करती है और बाधित नहीं करती है।

आपने उल्लेख नहीं किया है कि आप किस भाषा में काम कर रहे हैं, लेकिन एक .NET डेवलपर होने के नाते और इसका उल्लेख नहीं करने के लिए इसे कई बार देखा है।

मत लिखो:

catch(Exception ex)
{
  throw ex;
}

उपयोग:

catch(Exception ex)
{
  throw;
}

पूर्व स्टैक ट्रेस को रीसेट करता है और आपके शीर्ष स्तर को पूरी तरह से बेकार बना देता है!

TLDR

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


3
जब एक ही लकड़हारे को शीर्ष-स्तरीय अपवाद हैंडलर में उपयोग किया जाएगा, तो पकड़ में प्रवेश करने का क्या मतलब है?
व्यंग्यात्मक

आपके पास अतिरिक्त जानकारी हो सकती है (जैसे कि स्थानीय चर) जो आपके पास ढेर के शीर्ष पर पहुंच नहीं होगी। मैं उदाहरण के लिए वर्णन करने के लिए अद्यतन करूँगा।
Liath

2
उस स्थिति में, अतिरिक्त डेटा और आंतरिक अपवाद के साथ नए अपवाद को फेंक दें।
व्यंग्य

2
@ यूफोरिक हां, मैंने देखा है कि व्यक्तिगत रूप से भी, मैं व्यक्तिगत रूप से प्रशंसक नहीं हूं, क्योंकि आपको लगभग हर एक विधि / परिदृश्य के लिए नए प्रकार के अपवाद बनाने की आवश्यकता है, जो मुझे लगता है कि बहुत अधिक है। यहां लॉग लाइन जोड़ना (और संभवतः शीर्ष पर एक और) मुद्दों का निदान करते समय कोड के प्रवाह को स्पष्ट करने में मदद करता है
Liath

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

4

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

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

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

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


4

जब मैं try/catch/logहर विधि को देखता हूं तो यह चिंता पैदा करता है कि डेवलपर्स को पता नहीं था कि उनके आवेदन में क्या हो सकता है या नहीं हो सकता है, सबसे खराब मान लिया, और उन सभी बगों की वजह से हर जगह preemptively लॉग इन किया जिसकी वे उम्मीद कर रहे थे।

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

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

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

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


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

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

2

यदि आपको संदर्भ जानकारी रिकॉर्ड करने की आवश्यकता है जो पहले से ही अपवाद में नहीं है, तो आप इसे एक नए अपवाद में लपेटते हैं, और मूल अपवाद प्रदान करते हैं InnerException। इस तरह से आपके पास अभी भी मूल स्टैक ट्रेस संरक्षित है। इसलिए:

public static bool DoOperation(int num1, int num2)
{
    try
    {
        /* do some work with num1 and num2 */
    }
    catch (Exception ex)
    {
        throw new Exception("error occured while number 1 = {num1} and number 2 = {num2}", ex);
    }
}

Exceptionकंस्ट्रक्टर के लिए दूसरा पैरामीटर एक आंतरिक अपवाद प्रदान करता है। फिर आप एक ही स्थान पर सभी अपवादों को लॉग इन कर सकते हैं, और आपको अभी भी एक ही लॉग प्रविष्टि में पूर्ण स्टैक ट्रेस और प्रासंगिक जानकारी मिलती है।

आप एक कस्टम अपवाद वर्ग का उपयोग करना चाह सकते हैं, लेकिन बिंदु समान है।

try / catch / log / rethrow एक गड़बड़ है क्योंकि इससे भ्रामक लॉग हो जाएंगे - जैसे कि यदि प्रासंगिक जानकारी लॉग करने और शीर्ष स्तर के हैंडलर में वास्तविक अपवाद को लॉग करने के बीच एक अन्य थ्रेड में एक अलग अपवाद होता है? यदि नया अपवाद मूल में जानकारी जोड़ता है, तो कोशिश / पकड़ / फेंक ठीक है।


मूल अपवाद प्रकार के बारे में क्या? यदि हम लपेटते हैं, तो यह चला गया है। कोई समस्या है? कोई उदाहरण के लिए SqlTimeoutException पर भरोसा कर रहा था।
अधिकतम

@ मोम: मूल अपवाद प्रकार अभी भी आंतरिक अपवाद के रूप में उपलब्ध है।
जैक्सबी

मेरा मतलब वही था! अब हर कोई कॉल स्टैक, जो SqlException के लिए पकड़ रहा था, वह कभी नहीं मिलेगा।
अधिकतम

1

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

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

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

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


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

1
@DavidArno सच है, लेकिन आप जो भी संदर्भ प्रदान कर सकते हैं, वह विशिष्ट भी नहीं हो सकता है। नहीं तो आपके पास होगा try { tester.test(); } catch (NullPointerException e) { logger.error("Variable tester was null!"); }। स्टैक ट्रेस अधिकांश मामलों में पर्याप्त है, लेकिन इसकी कमी है, त्रुटि का प्रकार आमतौर पर पर्याप्त है।
नील
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.