"लॉग एंड थ्रो" को एक प्रतिमान क्यों माना जाता है? [बन्द है]


85

यह सवाल इस लेख के इर्द-गिर्द एक चर्चा से उछला , जहां मुझे कोई अच्छा जवाब नहीं मिला।

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


जवाबों:


121

मुझे लगता है कि इसका उत्तर काफी हद तक है क्योंकि अगर आप इसे संभाल नहीं सकते हैं तो आप इसे क्यों पकड़ रहे हैं? क्यों न जाने किसको संभाल सकें (या जिसे कोई विकल्प नहीं होने के बावजूद छोड़ दिया गया हो) उसे लॉग इन करें, अगर उन्हें लगता है कि यह लॉग-योग्य है?

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

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


आगे विस्तार के लिए, जेफ के जवाब पर टिप्पणियाँ देखें
मनु

8
लॉगिंग-एंड-रीथ्रोइंग ए एक्सडेशन व्होल्ड का एक कारण कारण को कम करना और एक विशिष्ट संदेश को लॉग करना है।
माइक Argyriou

11
उत्तर: स्टैक ट्रेस में वर्तमान बिंदु पर उपयोगी डिबग जानकारी उपलब्ध हो सकती है जो स्टैक ट्रेस में किसी अन्य बिंदु पर उपलब्ध नहीं होगी
rtconner

यदि नया अपवाद अधिक जानकारी या अधिक विशिष्ट के साथ अधिक सहायक हो तो कैचिंग और रीथ्रोइंग कभी-कभी सहायक होता है।
बोरजब

@Rtconner ने जो टिप्पणी की, उस पर खर्च करने के लिए: async कोड में यह हो सकता है कि पकड़ने वाले के पास वह संदर्भ न हो जो फेंकने वाले के लिए उपलब्ध है।
Nir Alfasi

53

लॉग-एंड-थ्रो एक अच्छा पैटर्न है यदि इकाई को पकड़ने और पुनर्विचार करने के कारण यह विश्वास करने का कारण है कि इसमें ऐसी जानकारी है जो कॉल स्टैक तक लॉग इन नहीं होगी - कम से कम सबसे वांछित फैशन में नहीं। इसके कुछ कारण हो सकते हैं:

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

4
# 1 वास्तव में एक समझदार सामान्य उपयोग का मामला है, हालांकि ओपी ने स्पष्ट रूप से "इसे फिर से पढ़ना (मूल स्टैक ट्रेस को संरक्षित करना)" के बारे में पूछा, इसलिए # 1 सही उत्तर नहीं है।
ज्योफ्री झेंग

@GeoffreyZheng: यह इस बात पर निर्भर करेगा कि मूल स्टैक ट्रेस लॉगिंग सुरक्षित रूप से "संरक्षण" के रूप में गिना जाएगा।
सुपरकैट

2
# 1 के बारे में: अपवाद सामग्री को उजागर करना (जैसे e.getMessage()UI पर प्रदर्शित / स्टैकट्रेस, साथ ही इसे REST प्रतिक्रिया के रूप में भेजना) को स्वयं भेद्यता के रूप में माना जाना चाहिए, क्योंकि रनटाइम अपवाद में किसी भी प्रकार की संवेदनशील जानकारी हो सकती है। # 2 के बारे में: आप अपवाद को उन सभी सूचनाओं को जोड़ सकते हैं जिन्हें आप ग्राहक को जानना चाहते हैं (+ मूल कारण), कुछ भी लॉग करने की आवश्यकता नहीं है।
निकिता बोसिक

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

20

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

क्रॉस-कटिंग चिंताओं का तर्क मूल रूप से यह है कि यह उन त्रुटियों से निपटने में समय की बर्बादी है जो आपको चिंता नहीं करते हैं। जब तक एक उपयुक्त हैंडलर नहीं मिल सकता है, कॉल स्टैक को त्रुटि बुलबुले में जाने के लिए बेहतर है।

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


1
मैं इस बात से सहमत हूं कि आपके लिए एक ही शीर्ष स्तरीय हैंडलर होना चाहिए। लेकिन मेरी राय में, उस शीर्ष स्तर के हैंडलर को "लॉग एंड थ्रो" होना चाहिए। तो तर्क जो "लॉग इन एंड थ्रो" पर है, जो नहीं है या नहीं?
मनु

@ मनु, मुझे लगता है कि यह एक एकल हैंडलर (केंद्रीकृत) है, तो यह ठीक है। यदि आप कोड डुप्लिकेट कर रहे हैं, तो यह ठीक नहीं है। मुझे नहीं लगता कि इससे ज्यादा कोई और है!
जेफ फोस्टर

5
@ मनु - उस मामले में शीर्ष स्तर का हैंडलर क्या फेंक रहा है? यह मुझे लगता है कि अगर इसे फेंकने के लिए कुछ उपलब्ध है, तो यह वास्तव में शीर्ष स्तर का हैंडलर नहीं है। और आप निश्चित रूप से रनटाइम पर्यावरण के लिए एक अपवाद को फिर से फेंकना नहीं चाहते हैं। कि एक दुर्घटनाग्रस्त पड़ाव के लिए सबसे अधिक अनुप्रयोगों लाएगा।
एरोह

1
@ बरोठा: मैं देख रहा हूं, आप जो कह रहे हैं, वह "लॉग एंड हैंडल" है (यदि आप शीर्ष स्तर के हैंडलर हैं) या "लॉग न करें और फेंकें (या अन्यथा संभाल लें)" यदि आप नहीं हैं। यह बात बताने के लिए धन्यवाद।
मनु

9

IMO लॉग एंड थ्रो, लिस्ट सरप्राइज़ के सिद्धांत का स्पष्ट उल्लंघन है।

यदि कॉल कॉल स्टैक को अपवाद को ठीक से संभाला जाता है, तो यह त्रुटि लॉग प्रविष्टि के लायक नहीं हो सकता है। और फिर यह एक त्रुटि लॉग प्रविष्टि खोजने के लिए भ्रमित है।


गैर-त्रुटि लॉग के बारे में क्या?
सु झांग

6
@ शुजांग मैं आपके प्रश्न को नहीं समझता। यदि कोई त्रुटि नहीं है, तो फेंकने के लिए कुछ भी नहीं है। बेशक आप कर सकते हैं और गैर-त्रुटि लॉग लिखना चाहिए।
बैस्टियन वोइग्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.