वे संदेश अन्य डेवलपर्स के लिए हैं
उन संदेशों को डेवलपर्स द्वारा एप्लिकेशन को डीबग करने में मदद करने के लिए पढ़ने की उम्मीद है । इसके दो रूप हो सकते हैं:
सक्रिय डिबगिंग। आप वास्तव में कोड लिखते समय डिबगर चला रहे हैं और यह पता लगाने की कोशिश कर रहे हैं कि क्या होता है। इस संदर्भ में, एक उपयोगी अपवाद आपको यह समझने में आसान बनाकर मार्गदर्शन करेगा कि क्या गलत हो रहा है, या अंततः एक वर्कअराउंड का सुझाव दे रहा है (हालांकि यह वैकल्पिक है)।
निष्क्रिय डिबगिंग। कोड उत्पादन में चलता है और विफल रहता है। अपवाद लॉग किया गया है, लेकिन आपको केवल संदेश और स्टैक ट्रेस मिलता है। इस संदर्भ में, एक उपयोगी अपवाद संदेश आपको बग को तुरंत स्थानीय बनाने में मदद करेगा।
चूंकि उन संदेशों को अक्सर लॉग किया जाता है, इसका मतलब यह भी है कि आपको संवेदनशील जानकारी (जैसे कि निजी कुंजी या पासवर्ड शामिल नहीं करना चाहिए, भले ही यह ऐप को डीबग करने के लिए उपयोगी हो सकता है)।
उदाहरण के लिए, IOSecurityException
किसी फ़ाइल को लिखते समय एक अपवाद के प्रकार को समस्या के बारे में बहुत स्पष्ट नहीं है: क्या ऐसा इसलिए है क्योंकि हमारे पास फ़ाइल तक पहुंचने की अनुमति नहीं है? या शायद हम इसे पढ़ सकते हैं, लेकिन लिख नहीं सकते? या हो सकता है कि फ़ाइल मौजूद नहीं है और हमारे पास वहाँ फ़ाइल बनाने की अनुमति नहीं है? या शायद यह बंद है (उम्मीद है, अपवाद का प्रकार इस मामले में अलग होगा, लेकिन व्यवहार में, प्रकार कभी-कभी गूढ़ हो सकते हैं)। या शायद कोड एक्सेस सिक्योरिटी हमें किसी भी I / O ऑपरेशन को करने से रोकती है?
बजाय:
IOSecurityException: फ़ाइल मिल गई थी, लेकिन इसकी सामग्री को पढ़ने की अनुमति से इनकार कर दिया गया था।
बहुत अधिक स्पष्ट है। यहां, हम तुरंत जानते हैं कि निर्देशिका पर अनुमतियाँ सही तरीके से सेट की गई हैं (अन्यथा, हम यह नहीं जान पाएंगे कि फ़ाइल मौजूद है), लेकिन फ़ाइल स्तर पर अनुमतियाँ समस्याग्रस्त हैं।
इसका अर्थ यह भी है कि यदि आप कोई अतिरिक्त जानकारी नहीं दे सकते हैं जो पहले से ही अपवाद के प्रकार में नहीं है, तो आप संदेश को खाली रख सकते हैं। DivisionByZeroException
एक अच्छा उदाहरण है जहां संदेश बेमानी है। दूसरी ओर, तथ्य यह है कि अधिकांश भाषाओं को आप अपने संदेश को निर्दिष्ट किए बिना एक अपवाद फेंकने देते हैं, एक अलग कारण के लिए किया जाता है: या तो क्योंकि डिफ़ॉल्ट संदेश पहले से ही उपलब्ध है, या क्योंकि यह बाद में उत्पन्न होगा (और इस की पीढ़ी) संदेश अपवाद प्रकार के भीतर संलग्न है, जो सही अर्थ बनाता है, "OOPly" बोल रहा है)।
ध्यान दें कि तकनीकी (अक्सर प्रदर्शन) कारणों के लिए, कुछ संदेश समाप्त होने की तुलना में बहुत अधिक गूढ़ होते हैं। .NET का NullReferenceException
:
वस्तु का संदर्भ वस्तु की आवृत्ति अनुसार सेट नहीं। है।
एक संदेश का एक उत्कृष्ट उदाहरण है जो सहायक नहीं है। एक सहायक संदेश होगा:
ऑब्जेक्ट संदर्भ product
को उस ऑब्जेक्ट के उदाहरण पर सेट नहीं किया जाता है जब उसे कॉल किया जाता है product.Price
।
वे संदेश अंतिम उपयोगकर्ताओं के लिए नहीं हैं!
अंतिम उपयोगकर्ताओं को अपवाद संदेश देखने की उम्मीद नहीं है। कभी नहीँ। हालांकि कुछ डेवलपर्स उन संदेशों को उपयोगकर्ताओं को दिखाते हैं, इससे उपयोगकर्ता अनुभव और निराशा होती है। इस तरह के संदेश:
वस्तु का संदर्भ वस्तु की आवृत्ति अनुसार सेट नहीं। है।
अंत उपयोगकर्ता के लिए बिल्कुल कुछ भी नहीं है, और हर कीमत पर बचा जाना चाहिए।
सबसे खराब स्थिति यह है कि एक वैश्विक कोशिश / पकड़ है जो उपयोगकर्ता के अपवाद को फेंकता है और ऐप को बाहर निकालता है। एक आवेदन जो अपने उपयोगकर्ताओं की परवाह करता है:
पहली जगह में अपवादों को संभालता है। अधिकांश लोगों को उपयोगकर्ता को परेशान किए बिना नियंत्रित किया जा सकता है। नेटवर्क डाउन है? क्यों कुछ सेकंड के लिए इंतजार न करें और फिर से प्रयास करें?
एक उपयोगकर्ता को एक असाधारण मामले में आवेदन का नेतृत्व करने से रोकता है। यदि आप उपयोगकर्ता को दो नंबर दर्ज करने के लिए कहते हैं और पहले एक को दूसरे नंबर से विभाजित करते हैं, तो आप उपयोगकर्ता को कुछ सेकंड बाद उसे दोष देने के लिए दूसरे मामले में शून्य दर्ज करने की अनुमति क्यों देंगे ? लाल रंग में टेक्स्ट बॉक्स को हाइलाइट करने के बारे में (सहायक टूल टिप के साथ यह बताते हुए कि संख्या शून्य से अलग होनी चाहिए) और सत्यापन बटन को अक्षम करने तक फ़ील्ड लाल रहता है?
किसी प्रपत्र में कोई क्रिया करने के लिए एक उपयोगकर्ता को आमंत्रित करता है जो त्रुटि नहीं है। किसी फ़ाइल तक पहुँचने के लिए पर्याप्त अनुमति नहीं हैं? उपयोगकर्ता को प्रशासनिक अनुमति देने, या एक अलग फ़ाइल चुनने के लिए क्यों नहीं कहेंगे?
यदि कुछ और काम नहीं करता है, तो एक सहायक, मैत्रीपूर्ण त्रुटि दिखाता है जो विशेष रूप से उपयोगकर्ता की निराशा को कम करने के लिए लिखा गया है, उपयोगकर्ता को यह समझने में मदद करता है कि क्या गलत हुआ और आखिरकार समस्या को हल करें, और भविष्य में त्रुटि को रोकने में भी उसकी मदद करें (जब लागू हो)।
आपके प्रश्न में, आपने एक अपवाद में दो संदेश देने का सुझाव दिया: डेवलपर्स के लिए एक तकनीकी, और अंतिम उपयोगकर्ताओं के लिए एक। हालांकि यह कुछ मामूली मामलों में एक मान्य सुझाव है, अधिकांश अपवाद एक स्तर पर निर्मित होते हैं जहां उपयोगकर्ताओं के लिए एक सार्थक संदेश का उत्पादन करना असंभव है। लो DivisionByZeroException
और कल्पना करो कि हम अपवाद को होने से नहीं रोक सकते और इसे स्वयं नहीं संभाल सकते। जब विभाजन होता है, तो क्या फ्रेमवर्क (क्योंकि यह फ्रेमवर्क है, न कि व्यवसाय कोड, जो अपवाद को फेंकता है) जानता है कि उपयोगकर्ता के लिए एक सहायक संदेश क्या होगा? बिलकुल नहीं:
शून्य से विभाजन हुआ। [ठीक है]
इसके बजाय, कोई इसे अपवाद को फेंकने दे सकता है, और फिर इसे एक उच्च स्तर पर पकड़ सकता है, जहां हम व्यापारिक संदर्भ जानते थे और वास्तव में अंतिम उपयोगकर्ता की मदद करने के लिए तदनुसार कार्य कर सकते थे, इस प्रकार कुछ दिखाते हैं:
फ़ील्ड D13 में फ़ील्ड E6 में एक के समान मान नहीं हो सकता है, क्योंकि उन मानों का घटाव एक भाजक के रूप में उपयोग किया जाता है। [ठीक है]
या हो सकता है:
एटीपी सेवा द्वारा सूचित मूल्य स्थानीय डेटा के साथ असंगत हैं। यह स्थानीय डेटा सिंक से बाहर होने के कारण हो सकता है। क्या आप शिपिंग जानकारी और पुनः प्रयास को सिंक्रनाइज़ करना चाहेंगे? [हाॅं नही]
वे संदेश पार्स करने के लिए नहीं हैं
अपवाद संदेशों के पार्स या प्रोग्रामिक रूप से उपयोग किए जाने की उम्मीद नहीं है । यदि आपको लगता है कि कॉलर द्वारा अतिरिक्त जानकारी की आवश्यकता हो सकती है, तो इसे संदेश के साथ-साथ अपवाद पक्ष में शामिल करें। यह महत्वपूर्ण है, क्योंकि संदेश बिना सूचना के परिवर्तन के अधीन है। प्रकार इंटरफ़ेस का एक हिस्सा है, लेकिन संदेश यह नहीं है: अपवाद हैंडलिंग के लिए कभी भी इस पर भरोसा न करें ।
अपवाद संदेश की कल्पना करें:
500 एमएस के इंतजार के बाद समय से पहले ही कैशिंग से जुड़ जाना। सर्वर प्रदर्शन में गिरावट की पहचान करने के लिए या तो टाइमआउट बढ़ाएं या प्रदर्शन निगरानी की जांच करें। कैशिंग सर्वर के लिए औसत प्रतीक्षा समय 6 एमएस था। पिछले महीने के लिए, 4 एमएस। अंतिम सप्ताह और 377 एमएस के लिए। आखिरी घंटे के लिए।
आप "500", "6", "4" और "377" मान निकालना चाहते हैं। उस दृष्टिकोण के बारे में थोड़ा सोचें जो आप पार्स करने के लिए उपयोग करेंगे, और उसके बाद ही पढ़ना जारी रखें।
आपके पास विचार है? महान।
अब, मूल डेवलपर ने एक टाइपो की खोज की:
Connecting to the caching sever timed out after waiting [...]
होना चाहिए:
↓
Connecting to the caching server timed out after waiting [...]
इसके अलावा, डेवलपर का मानना है कि माह / सप्ताह / एक घंटा विशेष रूप से प्रासंगिक नहीं है, इसलिए वह एक अतिरिक्त परिवर्तन भी करता है:
कैशिंग सर्वर के लिए औसत प्रतीक्षा समय 6 एमएस था। पिछले महीने के लिए, 5 एमएस। पिछले 24 घंटों और 377 एमएस के लिए। आखिरी घंटे के लिए।
आपके पार्स करने से क्या होता है?
पार्स करने के बजाय, आप अपवाद गुणों का उपयोग कर सकते हैं (जिसमें डेटा को क्रमबद्ध किया जा सकता है, जैसे ही कोई भी चाहता है, उसमें शामिल हो सकते हैं):
{
message: "Connecting to the caching [...]",
properties: {
"timeout": 500,
"statistics": [
{ "timespan": 1, "unit": "month", "average-timeout": 6 },
{ "timespan": 7, "unit": "day", "average-timeout": 4 },
{ "timespan": 1, "unit": "hour", "average-timeout": 377 },
]
}
}
अब इस डेटा का उपयोग करना कितना आसान है?
कभी-कभी (जैसे .NET के भीतर), संदेश को उपयोगकर्ता की भाषा में भी अनुवाद किया जा सकता है (IMHO, उन संदेशों का अनुवाद करना बिल्कुल गलत है, क्योंकि किसी भी डेवलपर को अंग्रेजी में पढ़ने में सक्षम होने की उम्मीद है)। ऐसे संदेशों को पार्स करना असंभव के करीब है।