Node.js में त्रुटि हैंडलिंग



पोस्ट में लेख "Node.js में त्रुटि हैंडलिंग" का अनुवाद शामिल है, जिसे जॉयंट कर्मचारियों द्वारा तैयार किया गया था। यह लेख 28 मार्च 2014 को कंपनी की वेबसाइट पर प्रकाशित किया गया था। डेव पाचेको बताते हैं कि लेख का उद्देश्य डेवलपर्स के बीच अशांति को खत्म करना है, जो नोड्स.जेएस में बग के साथ काम करने के लिए सर्वोत्तम प्रथाओं के बारे में है, साथ ही साथ नौसिखिया डेवलपर्स के लिए अक्सर उठने वाले सवालों का जवाब देना है।

Node.js में त्रुटि हैंडलिंग


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

शुरुआती डेवलपर्स में अक्सर निम्नलिखित प्रश्न होते हैं:



इस लेख में सात भाग हैं:

  1. परिचय। तथ्य यह है कि पाठक को लेख पढ़ने से पहले पता होना चाहिए।
  2. प्रोग्राम एरर और प्रोग्रामर एरर्स। त्रुटियों के प्रकार के साथ परिचित।
  3. समारोह लेखन टेम्पलेट्स। लेखन कार्यों के मौलिक सिद्धांत जो त्रुटियों के साथ सही काम को लागू करते हैं।
  4. लेखन कार्यों के लिए नियम। कार्य करते समय दिशानिर्देशों की एक सूची जिसका पालन किया जाना चाहिए।
  5. एक उदाहरण है। एक फ़ंक्शन लिखने का एक उदाहरण।
  6. सारांश। लेख में विचार किए गए मुख्य बिंदुओं की संक्षिप्त प्रस्तुति।
  7. आवेदन। त्रुटि ऑब्जेक्ट के लिए सामान्य फ़ील्ड नाम।


1. परिचय


पाठक को माना जाता है:


पाठक को यह समझना चाहिए कि try / catch निर्माण की उपस्थिति के बावजूद अपवाद फेंकना नीचे दिए गए कोड में काम क्यों नहीं करता है। 1
 function myFunc(callback) { /* *     */ try { doSomeAsyncOperation(function (err) { if (err) { throw (err); } }); } catch (ex) { callback(ex); } } 

पाठक को पता होना चाहिए कि Node.js में 3 मुख्य तरीके हैं जो एक समारोह में एक त्रुटि वापस कर सकते हैं:

  1. throw एरर फेंकना (एक अपवाद फेंकना)।
  2. पहले तर्क के रूप में एक त्रुटि ऑब्जेक्ट के साथ कॉलबैक फ़ंक्शन को कॉल करें।
  3. EventEmitter वर्ग की एक वस्तु पर 'error' घटना को उठाना।

यह माना जाता है कि पाठक Node.js. में डोमेन से परिचित नहीं है

पाठक को जावास्क्रिप्ट में त्रुटि और अपवाद के बीच अंतर को समझना चाहिए। त्रुटि Error वर्ग का कोई भी ऑब्जेक्ट है। त्रुटि क्लास कंस्ट्रक्टर द्वारा बनाई जा सकती है और थ्रोस्टैमेंट स्टेटमेंट का उपयोग करके फ़ंक्शन से लौटी या फेंक दी जा सकती है। जब कोई त्रुटि ऑब्जेक्ट फेंक दिया जाता है, तो एक अपवाद फेंक दिया जाता है। निम्नलिखित त्रुटियों को फेंकने का एक उदाहरण है (अपवाद फेंकना): 2

 throw new Error(' '); 

एक उदाहरण जहां कॉलबैक फ़ंक्शन में त्रुटि पारित की जाती है:

 callback(new Error(' ')); 

दूसरा विकल्प Node.js में अधिक सामान्य है, क्योंकि अधिकांश ऑपरेशनों की अतुल्यकालिकता के कारण। एक नियम के रूप में, पहले विकल्प का उपयोग केवल तब किया जाता है जब डेटा को JSON.parse करना (उदाहरण के लिए, JSON.parse ), जबकि अपवाद JSON.parse का try / catch निर्माण का उपयोग करके पकड़ा जाता है। यह जावा या C ++ और अन्य भाषाओं से Node.js को अलग करता है, जहां आपको अपवादों से अधिक बार सामना करना पड़ता है।


2. सॉफ्टवेयर एरर और प्रोग्रामर एरर


त्रुटियों को सशर्त रूप से दो प्रकारों में विभाजित किया जा सकता है: 3


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

ऐसे मामले हो सकते हैं, जब एक ही कारण से, प्रोग्राम त्रुटि और प्रोग्रामर त्रुटि दोनों हो। मान लीजिए कि एक HTTP सर्वर एक undefined मूल्य से एक फ़ील्ड को पढ़ने का प्रयास करता है, जो एक प्रोग्रामर त्रुटि है। नतीजतन, सर्वर क्रैश हो जाता है। क्लाइंट, उसी समय, ECONNRESET त्रुटि प्राप्त करता है, जिसे आमतौर पर Node.js द्वारा वर्णित किया जाता है: "सॉकेट हैंग-अप", इसके अनुरोध के जवाब में। क्लाइंट के लिए, यह एक सॉफ्टवेयर त्रुटि है और एक सही ढंग से लिखा गया क्लाइंट प्रोग्राम तदनुसार त्रुटि को संसाधित करेगा और काम करना जारी रखेगा।

प्रोग्राम एरर हैंडलर की अनुपस्थिति एक प्रोग्रामर एरर है। मान लें कि क्लाइंट प्रोग्राम, सर्वर के साथ कनेक्शन स्थापित करते समय, एक ECONNREFUSED त्रुटि का सामना करता है, परिणामस्वरूप, कनेक्शन ऑब्जेक्ट 'error' घटना उत्पन्न करता है, लेकिन इस घटना के लिए कोई हैंडलर फ़ंक्शन पंजीकृत नहीं हैं, इस कारण से प्रोग्राम क्रैश हो जाता है। इस स्थिति में, कनेक्शन त्रुटि एक सॉफ़्टवेयर त्रुटि है, हालांकि, कनेक्शन ऑब्जेक्ट 'त्रुटि' ईवेंट के लिए हैंडलर की अनुपस्थिति एक प्रोग्रामर त्रुटि है।

प्रोग्रामर त्रुटियों और प्रोग्राम त्रुटियों के बीच अंतर को समझना महत्वपूर्ण है। इसलिए, लेख को पढ़ना जारी रखने से पहले, सुनिश्चित करें कि आप इन अवधारणाओं को समझते हैं।

सॉफ्टवेयर एरर हैंडलिंग


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

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

हम परिदृश्यों को संभालने में संभावित त्रुटि को उजागर करते हैं:


प्रोग्रामर त्रुटि से निपटने


प्रोग्रामर त्रुटियों को संभालने का कोई सही तरीका नहीं है। परिभाषा के अनुसार, यदि ऐसी त्रुटि होती है, तो प्रोग्राम कोड गलत है। आप केवल कोड को ठीक करके समस्या को ठीक कर सकते हैं।

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

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


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


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


3. समारोह लेखन पैटर्न


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


फेंक, कॉलबैक या EventEmitter?


किसी फ़ंक्शन से त्रुटि वापस करने के तीन मुख्य तरीके हैं:

  1. तुल्यकालन में एक त्रुटि देता है। इसका मतलब यह है कि अपवाद उसी संदर्भ में होगा जिसमें फ़ंक्शन को बुलाया गया था। यदि कोशिश / पकड़ का उपयोग किया जाता है, तो अपवाद पकड़ा जाएगा। अन्यथा, कार्यक्रम विफल हो जाएगा (जब तक, निश्चित रूप से, अपवाद डोमेन को पकड़ता है या वैश्विक प्रक्रिया ऑब्जेक्ट के 'uncaughtException' ईवेंट हैंडलर, इस विकल्प को बाद में माना जाएगा)।
  2. पहले तर्क के रूप में एक त्रुटि ऑब्जेक्ट के साथ कॉलबैक फ़ंक्शन को कॉल करना एक अतुल्यकालिक फ़ंक्शन से त्रुटि को वापस करने के लिए सबसे अधिक उपयोग किया जाने वाला तरीका है। कॉलबैक फ़ंक्शन को कॉल करने के लिए एक सामान्य पैटर्न फॉर्म callback(err, results) की कॉल है, जहां केवल एक तर्क null से भिन्न मान ले सकता है।
  3. अधिक जटिल मामलों में, फ़ंक्शन EventEmitter वर्ग 'error' वस्तु की घटना 'error' उत्पन्न कर सकता है, फिर त्रुटि को संसाधित किया जाएगा यदि कोई हैंडलर घटना 'error' लिए पंजीकृत है। इस विकल्प का उपयोग किया जाता है यदि:
    • एक जटिल ऑपरेशन किया जाता है जो कई परिणाम या त्रुटियां देता है। एक उदाहरण एक डेटाबेस से रिकॉर्ड प्राप्त होगा। फ़ंक्शन EventEmitter वर्ग की एक वस्तु लौटाता है और जब प्रत्येक रिकॉर्ड को पुनर्प्राप्त किया जाता है, तो "end" 'row' इवेंट को उठाता है, जब सभी रिकॉर्ड पुनर्प्राप्त किए जाते हैं, तो "end" और यदि कोई त्रुटि होती है, तो 'error'
    • ऑब्जेक्ट एक जटिल ऑटोमेटोन है जो कई अतुल्यकालिक संचालन करता है। एक उदाहरण सॉकेट, जिससे घटनाओं है 'connect', 'end', 'timeout', 'drain'और 'close'यदि कोई त्रुटि होती है, तो ऑब्जेक्ट एक घटना उत्पन्न करेगा 'error'इस दृष्टिकोण का उपयोग करना, यह समझना महत्वपूर्ण है कि किन स्थितियों में त्रुटि हो सकती है, क्या इस मामले में अन्य घटनाएं हो सकती हैं, और वे किस क्रम में हो सकते हैं।


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

तो, फेंक का उपयोग कब करें, और कॉलबैक फ़ंक्शन या घटनाओं का उपयोग कब करें? यह दो कारकों पर निर्भर करता है:


अतुल्यकालिक कार्यों के लिए सॉफ़्टवेयर त्रुटियाँ अधिक सामान्य हैं। असिंक्रोनस फ़ंक्शन एक कॉलबैक फ़ंक्शन को एक तर्क के रूप में लेते हैं; जब कोई त्रुटि होती है, तो इसे त्रुटि ऑब्जेक्ट के साथ तर्क के रूप में कहा जाता है। यह दृष्टिकोण खुद को साबित कर चुका है और व्यापक रूप से उपयोग किया जाता है। एक उदाहरण Node.js मॉड्यूल है fsघटना दृष्टिकोण का भी उपयोग किया जाता है, लेकिन पहले से ही अधिक जटिल मामलों में।

समकालिक कार्यों में सॉफ़्टवेयर त्रुटियां एक नियम के रूप में हो सकती हैं, यदि फ़ंक्शन उपयोगकर्ता द्वारा दर्ज किए गए डेटा के साथ काम करता है (उदाहरण के लिए, JSON.parat)। ऐसे कार्यों में, एक त्रुटि तब होती है जब एक त्रुटि होती है, कम बार, त्रुटि वस्तु रिटर्न स्टेटमेंट द्वारा वापस आ जाती है।

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

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

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

याद रखें कि प्रोग्रामर त्रुटियां सामान्य प्रोग्राम प्रक्रिया का हिस्सा नहीं हैं। उन्हें पकड़ा और संसाधित नहीं किया जाना चाहिए। इसलिए, प्रोग्रामर त्रुटियों के लिए अपवादों को तत्काल फेंकने पर ये सिफारिशें ऊपर तैयार किए गए नियम का खंडन नहीं करती हैं कि एक ही फ़ंक्शन त्रुटियों को वापस करने के लिए एक तुल्यकालिक और अतुल्यकालिक दृष्टिकोण दोनों को लागू नहीं करना चाहिए।

मानी गई सिफारिशें तालिका में प्रस्तुत की गई हैं:

उदाहरण उदाहरणप्रकार प्रकारत्रुटित्रुटि का प्रकारकैसे लौटेंगे?कैसे संभालना है
fs.statअतुल्यकालिकफ़ाइल नहीं मिलीसॉफ्टवेयरकॉलबैकहैंडलर समारोह
JSON.parseएक समय काइनपुट त्रुटिसॉफ्टवेयरthrowtry / catch
fs.statअतुल्यकालिकआवश्यक तर्क गायब हैप्रोग्रामर त्रुटिthrowसंसाधित नहीं किया गया
(कार्य समाप्ति)

पहली प्रविष्टि सबसे आम उदाहरण प्रस्तुत करती है - एक एसिंक्रोनस फ़ंक्शन। दूसरी पंक्ति एक तुल्यकालिक फ़ंक्शन के लिए एक उदाहरण है, यह विकल्प कम सामान्य है। तीसरी पंक्ति में प्रोग्रामर की त्रुटि है; यह वांछनीय है कि ऐसे मामले केवल कार्यक्रम के विकास के दौरान होते हैं।


इनपुट त्रुटि: प्रोग्रामर त्रुटि या सॉफ्टवेयर त्रुटि?


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

आपको यह तय करना होगा कि तर्कों को जाँचने के लिए कौन सी कठोरता है। एक फ़ंक्शन की कल्पना करें जो connectएक आईपी पते और कॉलबैक फ़ंक्शन को तर्क के रूप में लेता है। मान लीजिए कि यह फ़ंक्शन एक तर्क के साथ बुलाया गया था जो आईपी पते से प्रारूप में भिन्न होता है, उदाहरण के लिए: "बॉब"। विचार करें कि इस मामले में क्या हो सकता है:


दोनों विकल्प समीक्षा की गई सिफारिशों को पूरा करते हैं, और यह आप पर निर्भर है कि कितनी सख्ती से जाँच करनी है। उदाहरण के लिए, Date.parse फ़ंक्शन विभिन्न प्रारूपों के तर्क स्वीकार करता है, लेकिन अच्छे कारण के लिए। फिर भी, अधिकांश कार्यों के लिए, पारित किए गए तर्कों की सख्ती से जांच करने की सिफारिश की जाती है। तर्कों की जाँच के लिए जितना अधिक अस्पष्ट हो, उतनी ही कठिन प्रक्रिया डिबगिंग कोड बन जाती है। एक नियम के रूप में, परीक्षण सख्त, बेहतर। और यहां तक ​​कि अगर प्रोग्राम के भविष्य के संस्करणों में आप अचानक किसी फ़ंक्शन के अंदर जांच के मानदंड को नरम करते हैं, तो आप अपने कोड को तोड़ने का जोखिम नहीं उठाते हैं।

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


डोमेन और process.on ('uncaughtException')


सॉफ़्टवेयर त्रुटियों को हमेशा एक विशिष्ट तंत्र का उपयोग करके पकड़ा जा सकता है: कॉलबैक फ़ंक्शन या इवेंट हैंडलर में try/ के माध्यम से एक वैश्विक वस्तु के डोमेन और घटनाओं को अक्सर अप्रत्याशित त्रुटियों के खिलाफ पुनर्बीमा के लिए उपयोग किया जाता है जो एक प्रोग्रामर बना सकता है। उपरोक्त विचारों को देखते हुए, इस दृष्टिकोण को दृढ़ता से हतोत्साहित किया जाता है।catch'error'process 'uncaughtException'


4. लेखन कार्य के लिए नियम


कार्य लिखते समय, इन दिशानिर्देशों का पालन करें:


  1. . :
    • ;
    • ;
    • , (: IP- ).

    - , .
    :
    • ( ),
    • ( try / catch ),
    • .

  2. Error ( ) .
    Error , . name message , stack .

  3. , .
    , propertyName propertyValue. remoteIp, . syscall , , , errno , . .

    :
    • name : .
    • message : . , , .
    • stack : . V8 , , .


    , , message . , .

  4. , .
    , , , callback- , , , . «». . verror .
    fetchConfig , . fetchConfig . .

        1.  
          1.1    
            1.1.1     DNS
            1.1.2  TCP     
            1.1.3     
           1.2।     
           1.3।   
          1.4.  
        2.   
        

    , 1.1.2 . fetchConfig , :

     myserver: Error: connect ECONNREFUSED 

    .
    , :

     myserver: failed to start up: failed to load configuration: failed to connect to database server: failed to connect to 127.0.0.1 port 1234: connect ECONNREFUSED 

    , :

     myserver: failed to load configuration: connection refused from database at 127.0.0.1 port 1234. 

    , , — .

    , :

    • , .
    • name , . , , , .
    • messageरैपिंग के दौरान फ़ील्ड को भी बदला जा सकता है, लेकिन आपको मूल ऑब्जेक्ट का संदेश नहीं बदलना चाहिए। फ़ील्ड के साथ कोई क्रिया न करें stack, जैसा कि ऊपर उल्लेख किया गया है, V8 stackइसे एक्सेस करते समय केवल एक ऑब्जेक्ट बनाता है, और यह एक काफी संसाधन-गहन प्रक्रिया है जो आपके प्रोग्राम के प्रदर्शन में महत्वपूर्ण कमी ला सकती है।

    जॉयंट में , हम त्रुटियों को लपेटने के लिए verror मॉड्यूल का उपयोग करते हैं, क्योंकि इसमें न्यूनतम सिंटैक्स होता है। लेखन के समय, कुछ सिफारिशों को मॉड्यूल में लागू नहीं किया गया है, लेकिन इसे अंतिम रूप दिया जाएगा।



5. उदाहरण


उदाहरण के लिए, एक फ़ंक्शन जो एक निर्दिष्ट IPv4 पते पर एक टीसीपी कनेक्शन बनाता है।

 /* *   TCP    IPv4 . : * * ip4addr    IPv4; * * tcpPort  , TCP ; * * timeout  ,   ,    *      ; * * callback     , *    ,  *   callback(null, socket),  socket  *   net.Socket,   , *    callback(err). * *       : * * SystemError  "connection refused", "host unreachable"   * ,    connect(2).  *     errno  err   *    . * * TimeoutError       *   timeout. * *       "remoteIp"  "remotePort". *   , ,    ,  . */ function connect(ip4addr, tcpPort, timeout, callback) { assert.equal(typeof (ip4addr), 'string', " 'ip4addr'    "); assert.ok(net.isIPv4(ip4addr), " 'ip4addr'   IPv4 "); assert.equal(typeof (tcpPort), 'number', " 'tcpPort'    "); assert.ok(!isNaN(tcpPort) && tcpPort > 0 && tcpPort < 65536, " 'tcpPort'        1  65535"); assert.equal(typeof (timeout), 'number', " 'timeout'    "); assert.ok(!isNaN(timeout) && timeout > 0, " 'timeout'    "); assert.equal(typeof (callback), 'function'); /*   */ } 

यह उदाहरण काफी आदिम है, लेकिन यह कई सिफारिशों को दर्शाता है:


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


6. सारांश




7. परिशिष्ट: सामान्य त्रुटि फ़ील्ड नाम


यह दृढ़ता से अनुशंसा की जाती है कि तालिका में दिए गए फ़ील्ड नामों का उपयोग त्रुटि वस्तुओं का विस्तार करने के लिए किया जाए। प्रस्तुत नाम मानक Node.js मॉड्यूल में उपयोग किए जाते हैं, उन्हें त्रुटि संचालकों में उपयोग किया जाना चाहिए, साथ ही त्रुटि संदेश उत्पन्न करते समय भी।
localHostnameDNS- (, , )
localIpIP- (, , )
localPortTCP (, , )
remoteHostnameDNS- (, , )
remoteIpIP- (, , )
remotePort(, , )
path, (IPC-) (, , )
srcpath(, )
dstpath(, )
hostnameDNS (, , IP-)
ipIP- (, , DNS-)
propertyName(, , )
propertyValue(, , )
syscall
errnoerrno (, "ENOENT" )



1 शुरुआती अक्सर एक ही गलती करते हैं। इस उदाहरण में, try/ catchऔर अपवाद को फेंकने वाले फ़ंक्शन कॉल को अतुल्यकालिक फ़ंक्शन के कारण विभिन्न संदर्भों में निष्पादित किया जाएगा doSomeAsyncOperation, इसलिए, अपवाद नहीं पकड़ा जाएगा।
2 जावास्क्रिप्ट में, यह throwअन्य प्रकारों के मूल्यों के साथ काम कर सकता है, लेकिन यह त्रुटि वर्ग की वस्तुओं का उपयोग करने के लिए अनुशंसित है। यदि थ्रोस्टैटेमेंट में अन्य मानों का उपयोग किया जाता है, तो कॉल स्टैक प्राप्त करना असंभव होगा, जिसके कारण त्रुटि हुई, जो कोड डीबगिंग को जटिल करेगा।
3 ये अवधारणाएँ Node.js. के आगमन से बहुत पहले उत्पन्न हुईं जावा में, चेक किए गए और अनियंत्रित अपवादों को अनुरूप माना जा सकता है। सी में, प्रोग्रामर त्रुटियों के साथ काम करने के लिए बयान दिए जाते हैं
4 उपरोक्त उदाहरण बहुत ही ठोस लग सकता है, यह इसलिए है क्योंकि यह काल्पनिक नहीं है, हम वास्तव में इस समस्या में भाग गए, यह अप्रिय था।

Source: https://habr.com/ru/post/In222761/


All Articles