दिलचस्प पोस्ट
डिफ़ॉल्ट URL स्कीम के साथ कैसे संभालना है ExternalContext.redirect () का उपयोग करके रीडायरेक्ट पृष्ठ पर चेस संदेश जोड़ना आंशिक सीमा के साथ HTML5 / CSS3 मंडल बूटस्ट्रैप 3 शेवरॉन आइकन के साथ स्थिति को संक्षिप्त करें ऐप्पकपाटव 7 – वी 21 नेविगेशन ड्रॉवर हैमबर्गर आइकन नहीं दिखा रहा है मैं Dapper.Net में कई क्वेरी में एक कैसे लिख सकता हूं? IE में बंद एनिमेटेड GIF विंडोज पर एमबीसीएस और यूटीएफ -8 के बीच अंतर एंड्रॉइड में होम स्क्रीन प्रोग्राम को लॉन्च कैसे करें एक छवि सी # का आकार बदलें PHP की छुपी हुई विशेषताएं? PHP में समयक्षेत्र रूपांतरण तिथि (डेटस्ट्रिंग) और नए दिनांक (डेटस्ट्रिंग) के बीच अंतर SQLite कैसे स्केलेबल है? क्या पीडीओ का उपयोग करने के लिए अच्छे ट्यूटोरियल हैं?

नोड। जेएस बेस्ट प्रैक्टिस अपवाद हैंडलिंग

मैं बस कुछ दिनों पहले node.js बाहर की कोशिश कर रहा शुरू कर दिया। मुझे एहसास हुआ है कि जब भी मेरे कार्यक्रम में एक अनियंत्रित अपवाद होता है तब नोड समाप्त हो जाता है यह सामान्य सर्वर कंटेनर से अलग है, जिसमें मुझे पता चला है कि जब वर्क थ्रेड मर जाता है जब मैनेजमेंट अपवाद होते हैं और कंटेनर अभी भी अनुरोध प्राप्त करने में सक्षम होगा। इससे कुछ सवाल उठते हैं:

  • क्या process.on('uncaughtException') केवल एक ही प्रभावशाली तरीके से इसकी रक्षा करता है?
  • प्रोसेस process.on('uncaughtException') असिंक्रोनस प्रोसेस के निष्पादन के साथ-साथ असम्बद्ध अपवाद को भी पकड़ सकता है?
  • क्या कोई ऐसा मॉड्यूल है जो पहले से ही बनाया गया है (जैसे कि ईमेल भेजना या फाइल को लिखना) कि मैं बिना किसी अपवाद के मामले में फायदा उठा सकता हूं?

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

वेब के समाधान से एकत्रित समाधान "नोड। जेएस बेस्ट प्रैक्टिस अपवाद हैंडलिंग"

अद्यतन: जॉयंट के इस उत्तर में उल्लिखित अपने स्वयं के गाइड हैं निम्न जानकारी एक सारांश का अधिक है:

सुरक्षित रूप से "फेंकने" त्रुटियाँ

आदर्श रूप से हम बिना कुटिल त्रुटियों को जितना संभव हो, उससे बचाना चाहते हैं, जैसे कि, वाकई त्रुटि को फेंकने के बजाय, हम इसके बजाय हमारे कोड वास्तुकला के आधार पर निम्न विधियों में से किसी एक का उपयोग करके त्रुटि "फेंक" कर सकते हैं:

  • तुल्यकालिक कोड के लिए, यदि कोई त्रुटि होती है, तो त्रुटि लौटाएं:

     // Define divider as a syncrhonous function var divideSync = function(x,y) { // if error condition? if ( y === 0 ) { // "throw" the error safely by returning it return new Error("Can't divide by zero") } else { // no error occured, continue on return x/y } } // Divide 4/2 var result = divideSync(4,2) // did an error occur? if ( result instanceof Error ) { // handle the error safely console.log('4/2=err', result) } else { // no error occured, continue on console.log('4/2='+result) } // Divide 4/0 result = divideSync(4,0) // did an error occur? if ( result instanceof Error ) { // handle the error safely console.log('4/0=err', result) } else { // no error occured, continue on console.log('4/0='+result) } 
  • कॉलबैक-आधारित (यानी एसिंक्रोनस) कोड के लिए, कॉलबैक का पहला तर्क err , अगर कोई त्रुटि हुई तो त्रुटि होती है, अगर कोई त्रुटि नहीं होती है तो err null है null कोई अन्य तर्क err तर्क का पालन करता है:

     var divide = function(x,y,next) { // if error condition? if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero")) } else { // no error occured, continue on next(null, x/y) } } divide(4,2,function(err,result){ // did an error occur? if ( err ) { // handle the error safely console.log('4/2=err', err) } else { // no error occured, continue on console.log('4/2='+result) } }) divide(4,0,function(err,result){ // did an error occur? if ( err ) { // handle the error safely console.log('4/0=err', err) } else { // no error occured, continue on console.log('4/0='+result) } }) 
  • घटनात्मक कोड के लिए, जहां त्रुटि कहीं भी हो सकती है, त्रुटि को फेंकने के बजाय, इसके बजाय error ईवेंट को आग में डालें :

     // Definite our Divider Event Emitter var events = require('events') var Divider = function(){ events.EventEmitter.call(this) } require('util').inherits(Divider, events.EventEmitter) // Add the divide function Divider.prototype.divide = function(x,y){ // if error condition? if ( y === 0 ) { // "throw" the error safely by emitting it var err = new Error("Can't divide by zero") this.emit('error', err) } else { // no error occured, continue on this.emit('divided', x, y, x/y) } // Chain return this; } // Create our divider and listen for errors var divider = new Divider() divider.on('error', function(err){ // handle the error safely console.log(err) }) divider.on('divided', function(x,y,result){ console.log(x+'/'+y+'='+result) }) // Divide divider.divide(4,2).divide(4,0) 

सुरक्षित रूप से "पकड़ने" त्रुटियाँ

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

  • जब हम जानते हैं कि त्रुटि कहाँ होती है, तो हम उस अनुभाग को एक नोड.जेएस डोमेन में लपेट सकते हैं

     var d = require('domain').create() d.on('error', function(err){ // handle the error safely console.log(err) }) // catch the uncaught errors in this asynchronous or synchronous code block d.run(function(){ // the asynchronous or synchronous code that we want to catch thrown errors on var err = new Error('example') throw err }) 
  • अगर हम जानते हैं कि त्रुटि कहां होती है तो तुल्यकालिक कोड है, और जो भी कारण डोमेन का उपयोग नहीं कर सकता (शायद नोड का पुराना संस्करण), हम कोशिश पकड़ने का प्रयोग कर सकते हैं:

     // catch the uncaught errors in this synchronous code block // try catch statements only work on synchronous code try { // the synchronous code that we want to catch thrown errors on var err = new Error('example') throw err } catch (err) { // handle the error safely console.log(err) } 

    हालांकि, सावधान रहें कि try...catchtry...catch एसिंक्रोनस कोड में पकड़ें, एक एसिंक्रोनस फेंक दिया त्रुटि के रूप में नहीं try...catch :

     try { setTimeout(function(){ var err = new Error('example') throw err }, 1000) } catch (err) { // Example error won't be caught here... crashing our app // hence the need for domains } 

    try...catch साथ सावधान रहने के लिए एक और चीज try...catch को अपने पूरा होने की कॉलबैक को ट्रिगर स्टेटमेंट के अंदर लपेटने का जोखिम है:

     var divide = function(x,y,next) { // if error condition? if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero")) } else { // no error occured, continue on next(null, x/y) } } var continueElsewhere = function(err, result){ throw new Error('elsewhere has failed') } try { divide(4, 2, continueElsewhere) // ^ the execution of divide, and the execution of // continueElsewhere will be inside the try statement } catch (err) { console.log(err.stack) // ^ will output the "unexpected" result of: elsewhere has failed } 

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

  • अंत में, ऐसे मामले में जहां किसी जगह में एक कुख्यात त्रुटि उत्पन्न होती है जो किसी डोमेन में लिपटे नहीं हुई थी या एक पकड़ने की कोशिश की गई थी, तो हम अपने आवेदन को uncaughtException श्रोता का उपयोग करके क्रैश नहीं कर सकते (हालांकि ऐसा करने से यह एप्लिकेशन अज्ञात में डाल सकता है राज्य ):

     // catch the uncaught errors that weren't wrapped in a domain or try catch statement // do not use this in modules, but only in applications, as otherwise we could have multiple of these bound process.on('uncaughtException', function(err) { // handle the error safely console.log(err) }) // the asynchronous or synchronous code that emits the otherwise uncaught error var err = new Error('example') throw err 

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


नोड। जे एस त्रुटि से निपटने की सर्वोत्तम प्रक्रियाएं


नंबर 1: एसिंक त्रुटि हैंडलिंग के लिए वादों का उपयोग करें

टीएल; डीआर: कॉलबैक शैली में एसिंक त्रुटियों को संभालने संभवतया नरक (कयामत के पिरामिड उर्फ) का सबसे तेज़ तरीका है। आप अपने कोड को सबसे अच्छा उपहार दे सकते हैं बजाय एक सम्मानित वायर्ड लाइब्रेरी जो बहुत कॉम्पैक्ट और परिचित कोड सिंटैक्स प्रदान करता है जैसे try-catch

अन्यथा: नोड.जेएस कॉलबैक स्टाइल, फंक्शन (गलती, प्रतिक्रिया), असामान्य तरीके से गैर-रिटेन करने योग्य कोड है, क्योंकि आकस्मिक कोड, अत्यधिक घोंसले के शिकार और अजीब कोडिंग पैटर्न

कोड उदाहरण – अच्छा

 doWork() .then(doWork) .then(doError) .then(doWork) .catch(errorHandler) .then(verify); 

कोड उदाहरण विरोधी पैटर्न – कॉलबैक शैली त्रुटि हैंडलिंग

 getData(someParameter, function(err, result){ if(err != null) //do something like calling the given callback function and pass the error getMoreData(a, function(err, result){ if(err != null) //do something like calling the given callback function and pass the error getMoreData(b, function(c){ getMoreData(d, function(e){ ... }); }); }); }); }); 

ब्लॉग उद्धरण: "हमें वादों के साथ एक समस्या है" (ब्लॉग पॉचडब से, कीवर्ड "नोड वादे" के लिए 11 स्थान पर है)

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


संख्या 2: केवल अंतर्निहित त्रुटि ऑब्जेक्ट का उपयोग करें

टीएल; डीआर: कोड को देखने के लिए यह बहुत आम है जो स्ट्रिंग के रूप में त्रुटियों या एक कस्टम प्रकार के रूप में फेंकता है – यह त्रुटि हैंडलिंग लॉजिक और मॉड्यूल के बीच अंतरता को जटिल बनाता है चाहे आप एक वादा को अस्वीकार करें, अपवाद फेंकें या गलती की त्रुटि – Node.JS निर्मित में त्रुटि ऑब्जेक्ट एकरूपता बढ़ाता है और त्रुटि की जानकारी को नुकसान से बचाता है

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

कोड उदाहरण – यह सही कर रहा है

  //throwing an Error from typical function, whether sync or async if(!productToAdd) throw new Error("How can I add new product when no value provided?"); //'throwing' an Error from EventEmitter const myEmitter = new MyEmitter(); myEmitter.emit('error', new Error('whoops!')); //'throwing' an Error from a Promise return new promise(function (resolve, reject) { DAL.getProduct(productToAdd.id).then((existingProduct) =>{ if(existingProduct != null) return reject(new Error("Why fooling us and trying to add an existing product?")); 

कोड उदाहरण विरोधी पैटर्न

 //throwing a String lacks any stack trace information and other important properties if(!productToAdd) throw ("How can I add new product when no value provided?"); 

ब्लॉग उद्धरण: "एक स्ट्रिंग एक त्रुटि नहीं है" (ब्लॉग विस्त्र से, कीवर्ड "नोड। जेएस त्रुटि ऑब्जेक्ट" के लिए 6 स्थान पर है)

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


नंबर 3: परिचालन बनाम प्रोग्रामर त्रुटियों को भेद

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

अन्यथा: एक त्रुटि दिखाई देने पर आप हमेशा आवेदन को पुनः आरंभ कर सकते हैं, लेकिन एक नाबालिग और भविष्यवाणी की गई त्रुटि (परिचालन त्रुटि) की वजह से ~ 5000 ऑनलाइन उपयोगकर्ता नीचे क्यों दे सकते हैं? विपरीत भी आदर्श नहीं है – जब कोई अज्ञात समस्या (प्रोग्रामर त्रुटि) उत्पन्न हुई तो अपरिवर्तित व्यवहार का नेतृत्व करने पर एप्लिकेशन को ऊपर रखा गया। दोनों को विभेदित करने के लिए समझदारी से कार्य करने और दिए गए संदर्भ के आधार पर संतुलित दृष्टिकोण लागू करने की अनुमति मिलती है

कोड उदाहरण – यह सही कर रहा है

  //throwing an Error from typical function, whether sync or async if(!productToAdd) throw new Error("How can I add new product when no value provided?"); //'throwing' an Error from EventEmitter const myEmitter = new MyEmitter(); myEmitter.emit('error', new Error('whoops!')); //'throwing' an Error from a Promise return new promise(function (resolve, reject) { DAL.getProduct(productToAdd.id).then((existingProduct) =>{ if(existingProduct != null) return reject(new Error("Why fooling us and trying to add an existing product?")); 

कोड उदाहरण – संचालन के रूप में एक त्रुटि चिन्हांकित (विश्वसनीय)

 //marking an error object as operational var myError = new Error("How can I add new product when no value provided?"); myError.isOperational = true; //or if you're using some centralized error factory (see other examples at the bullet "Use only the built-in Error object") function appError(commonType, description, isOperational) { Error.call(this); Error.captureStackTrace(this); this.commonType = commonType; this.description = description; this.isOperational = isOperational; }; throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true); //error handling code within middleware process.on('uncaughtException', function(error) { if(!error.isOperational) process.exit(1); }); 

ब्लॉग उद्धरण : "अन्यथा आप राज्य को जोखिम में डालते हैं" (ब्लॉग डीबग करने योग्य से, कीवर्ड "नोड। जेएस अनक्रेत अपवाद" के लिए 3 स्थान पर है)

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


नंबर 4: मध्यस्थों के माध्यम से, लेकिन मध्यवर्ती के भीतर त्रुटियां संभाल लें

टीएल; डीआर: त्रुटि प्रबंधन से निपटने में त्रुटि जैसे एडमिन और लॉगिंग को एक समर्पित और केंद्रीकृत ऑब्जेक्ट में समझाया जाना चाहिए, जब कोई त्रुटि आती है तो सभी अंत-बिंदु (जैसे एक्सप्रेस मिडलवेयर, क्रोन जॉब, यूनिट टेस्टिंग) कॉल करते हैं।

अन्यथा: किसी एक स्थान के भीतर त्रुटियों को संभालने से कोड दोहराव हो सकता है और शायद त्रुटियों को अनुचित तरीके से संभाला जाएगा

कोड उदाहरण – एक सामान्य त्रुटि प्रवाह

 //DAL layer, we don't handle errors here DB.addDocument(newCustomer, (error, result) => { if (error) throw new Error("Great error explanation comes here", other useful parameters) }); //API route code, we catch both sync and async errors and forward to the middleware try { customerService.addNew(req.body).then(function (result) { res.status(200).json(result); }).catch((error) => { next(error) }); } catch (error) { next(error); } //Error handling middleware, we delegate the handling to the centrzlied error handler app.use(function (err, req, res, next) { errorHandler.handleError(err).then((isOperationalError) => { if (!isOperationalError) next(err); }); }); 

ब्लॉग उद्धरण: "कभी-कभी निचला स्तर उनके कॉलर को त्रुटि का प्रचार करने के अलावा उपयोगी कुछ नहीं कर सकते हैं" (ब्लॉग जॉयेंट से, कीवर्ड "नोड। जे एस त्रुटि से निपटने" के लिए 1 स्थान पर है)

"… आप स्टैक के कई स्तरों पर उसी त्रुटि को संभालने के लिए समाप्त कर सकते हैं। ऐसा तब होता है जब निचले स्तर उनके कॉलर को त्रुटि का प्रचार करने के अलावा उपयोगी कुछ नहीं कर सकते हैं, जो इसके कॉलर को त्रुटि का प्रचार करता है, और इसी तरह। केवल शीर्ष-स्तरीय कॉलर जानता है कि उचित प्रतिक्रिया क्या है, चाहे वह ऑपरेशन का पुन: प्रयास करें, उपयोगकर्ता को एक त्रुटि की रिपोर्ट करें, या कुछ और। लेकिन इसका यह मतलब नहीं है कि आपको सभी त्रुटियों को एक शीर्ष-स्तर पर रिपोर्ट करने का प्रयास करना चाहिए कॉलबैक, क्योंकि उस कॉलबैक को नहीं पता कि किस संदर्भ में त्रुटि हुई "


संख्या 5: स्वॉगगर का उपयोग करके दस्तावेज़ API त्रुटियां

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

अन्यथा: एक एपीआई क्लाइंट क्रैश और पुनरारंभ करने का निर्णय ले सकता है क्योंकि उसे एक त्रुटि मिली जिसे वह समझ नहीं सका। नोट: आपके एपीआई का कॉलर आप हो सकता है (एक माइक्रोसर्विसिव पर्यावरण में बहुत विशिष्ट)

ब्लॉग उद्धरण: "आपको अपने कॉल करने वालों को बताएं कि कौन-सी त्रुटियां हो सकती हैं" (ब्लॉग जॉयेंट से, कीवर्ड "नोड। जे एस लॉगिंग" के लिए 1 स्थान पर है)

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


संख्या 6: इस प्रक्रिया को सुन्दर तरीके से बंद करें जब एक अजनबी शहर में आता है

टीएल; डीआर: जब कोई अज्ञात त्रुटि आती है (एक डेवलपर त्रुटि, सर्वोत्तम प्रैक्टिस नंबर # 3 देखें) – एप्लिकेशन स्वास्थ्य के बारे में अनिश्चितता है एक आम प्रथा का सुझाव है कि प्रक्रिया को पुनरारंभ करना एक 'आराम' उपकरण जैसे फ़ोरएयर और पीएम 2 का उपयोग कर

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

कोड उदाहरण – क्रैश करने का फैसला करना

 //deciding whether to crash when an uncaught exception arrives //Assuming developers mark known operational errors with error.isOperational=true, read best practice #3 process.on('uncaughtException', function(error) { errorManagement.handler.handleError(error); if(!errorManagement.handler.isTrustedError(error)) process.exit(1) }); //centralized error handler encapsulates error-handling related logic function errorHandler(){ this.handleError = function (error) { return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError); } this.isTrustedError = function(error) { return error.isOperational; } 

ब्लॉग उद्धरण: "त्रुटि संभाल पर विचार के तीन स्कूल हैं" (ब्लॉग jsrecipes से)

… त्रुटि संभाल पर मुख्यतः तीन विचार वाले स्कूल हैं: 1. एप्लिकेशन को दुर्घटनाग्रस्त होने दें और उसे पुनरारंभ करें। 2. सभी संभावित त्रुटियों को संभाल और दुर्घटना कभी नहीं। 3. दोनों के बीच संतुलित दृष्टिकोण


नंबर 7: त्रुटि दृश्यता बढ़ाने के लिए परिपक्व लॉगर का उपयोग करें

टीएल; डीआर: विंस्टन, बनन या लॉज 4 जे जैसे परिपक्व लॉगिंग औजारों का एक सेट, गति की त्रुटि की खोज और समझने में तेज होगा इसलिए console.log के बारे में भूल जाओ

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

कोड उदाहरण – कार्य में विंस्टन लॉगर

 //your centralized logger object var logger = new winston.Logger({ level: 'info', transports: [ new (winston.transports.Console)(), new (winston.transports.File)({ filename: 'somefile.log' }) ] }); //custom code somewhere using the logger logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' }); 

ब्लॉग उद्धरण: "कुछ आवश्यकताएं (एक लकड़हारा के लिए) की पहचान करने दें:" (ब्लॉग मजबूत ब्लॉग से)

… कुछ आवश्यकताएं (एक लकड़हारा के लिए) की पहचान करें: 1. प्रत्येक लॉग लाइन के लिए समय स्टाम्प। यह एक बहुत आत्म व्याख्यात्मक है – आपको यह बताने में सक्षम होना चाहिए कि जब प्रत्येक लॉग प्रविष्टि हुई। 2. लॉगिंग प्रारूप को इंसानों और मशीनों द्वारा आसानी से पचने योग्य होना चाहिए। 3. कई विन्यास गंतव्य स्ट्रीम के लिए अनुमति देता है। उदाहरण के लिए, आप एक फाइल में ट्रेस लॉग लिख सकते हैं, लेकिन जब कोई त्रुटि आ जाती है, तो उसी फाइल को लिखें, फिर त्रुटि फ़ाइल में और एक ही समय में एक ईमेल भेजें …


Number8: एपीएम उत्पादों का प्रयोग करके त्रुटियों और डाउनटाइम की खोज करें

टीएल; डीआर: मॉनिटरिंग और परफॉर्मेंस प्रोडक्ट्स (उर्फ एपीएम) आपके कोडेबेस या एपीआई को लगातार गेज करते हैं, ताकि वे त्रुटियों, दुर्घटनाओं और धीमी हिस्सों पर ऑटो-मैजिकिक रूप से हाइलाइट कर सकें जिन्हें आप याद कर रहे थे

अन्यथा: आप एपीआई प्रदर्शन और डाउनटाईम को मापने के लिए बहुत मेहनत कर सकते हैं, शायद आपको कभी नहीं पता होगा कि असली दुनिया परिदृश्य के तहत आपके सबसे धीमी कोड भाग हैं और ये कैसे यूएक्स को प्रभावित करते हैं

ब्लॉग उद्धरण: "एपीएम उत्पाद खंड" (ब्लॉग से योनि गोल्डबर्ग)

"… एपीएम उत्पादों में 3 प्रमुख खंड होते हैं: 1. वेबसाइट या एपीआई निगरानी – बाहरी सेवाओं जो लगातार HTTP अनुरोधों के द्वारा अपटाइम और प्रदर्शन की निगरानी करते हैं। कुछ मिनटों में सेटअप किया जा सकता है। कुछ चयनित दावेदार हैं: पिंगडोम, अपटाइम रोबोट, और न्यू रिकिक 2 कोड इंस्ट्रूमेंटेशन – उत्पादों के परिवार के लिए आवेदन को धीमा कोड का पता लगाने, अपवाद आंकड़े, प्रदर्शन की निगरानी और कई और अधिक लाभ के लिए आवेदन के भीतर एक एजेंट को एम्बेड करने की आवश्यकता होती है। कुछ चयनित दावेदार निम्नलिखित हैं: नई अवशेष, ऐप डायनेमिक्स 3. ऑपरेशनल इंटेलिजेंस डैशबोर्ड – ये लाइन उत्पादों की मैट्रिक्स और क्यूरेटेड सामग्री के साथ ऑप्स टीम की सुविधा प्रदान करने पर ध्यान केंद्रित किया जाता है जो आसानी से आवेदन प्रदर्शन के शीर्ष पर रहने में मदद करता है। यह आमतौर पर सूचना के कई स्रोतों (एप्लिकेशन लॉग, डीबी लॉग, सर्वर लॉग, आदि) और अग्रिम डैशबोर्ड डिज़ाइन काम कुछ चयनित दावेदार निम्नलिखित हैं: डेटादोग, स्प्लक "


ऊपर एक संक्षिप्त संस्करण है – यहां और अधिक सर्वोत्तम अभ्यास और उदाहरण देखें

आप बिना अपवादों को पकड़ सकते हैं, लेकिन यह सीमित उपयोग का है। देखें http://debuggable.com/posts/node-js-dealing-with-uncaught-exceptions:4c933d54-1428-443c-928d-4e1ecbdd56cb

monit , forever या upstart को क्रैश होने पर नोड प्रक्रिया को पुनरारंभ करने के लिए उपयोग किया जा सकता है। एक शानदार शटडाउन सबसे अच्छा है जिसके लिए आप आशा कर सकते हैं (उदाहरण के लिए सभी इन-मेमोरी डेटा को बिना किसी अपवाद के हैंडलर में सहेजें)।

नोडजेएस डोमेन नोडजे में त्रुटियों को संभालने का सबसे अधिक समय है। डोमेन दोनों त्रुटि / अन्य घटनाओं के साथ-साथ पारंपरिक रूप से फेंक गई वस्तुओं को भी कब्जा कर सकता है। डोमेन इंटरसेप्ट विधि के माध्यम से पहले तर्क के रूप में पारित त्रुटि के साथ कॉलबैक को संभालने के लिए कार्यक्षमता भी प्रदान करता है।

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

सिंक्रोनस कोड में, ऊपर पर्याप्त है – जब कोई त्रुटि होती है या तो आपको इसे फेंक दिया जाता है, या आप उसे पकड़ते हैं और वहां संभालते हैं, जो आपको वापस लाने के लिए आवश्यक डेटा वापस लेते हैं

 try { //something } catch(e) { // handle data reversion // probably log too } 

जब एक एसिंक्रोनस कॉलबैक में त्रुटि होती है, तो आपको या तो डेटा के रोलबैक को पूरी तरह से संभाल करने में सक्षम होने की आवश्यकता होती है (साझा स्थिति, डेटाबेस जैसे बाहरी डेटा आदि)। या आपको यह संकेत देने के लिए कुछ सेट करना होगा कि कोई अपवाद हुआ है – जहां तक ​​आप उस ध्वज की परवाह करते हैं, आपको कॉलबैक को पूरा करने का इंतजार करना होगा।

 var err = null; var d = require('domain').create(); d.on('error', function(e) { err = e; // any additional error handling } d.run(function() { Fiber(function() { // do stuff var future = somethingAsynchronous(); // more stuff future.wait(); // here we care about the error if(err != null) { // handle data reversion // probably log too } })}); 

इनमें से कुछ कोड बदसूरत है, लेकिन आप इसे सुंदर बनाने के लिए अपने लिए पैटर्न बना सकते हैं, उदाहरण के लिए:

 var specialDomain = specialDomain(function() { // do stuff var future = somethingAsynchronous(); // more stuff future.wait(); // here we care about the error if(specialDomain.error()) { // handle data reversion // probably log too } }, function() { // "catch" // any additional error handling }); 

अपडेट (2013-09):

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

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

एक उदाहरण:

 returnsAFuture().then(function() { console.log('1') return doSomething() // also returns a future }).then(function() { console.log('2') throw Error("oops an error was thrown") }).then(function() { console.log('3') }).catch(function(exception) { console.log('handler') // handle the exception }).done() 

यह एक सामान्य प्रयास-पकड़ को नकल करता है, भले ही ये टुकड़े अतुल्यकालिक होते हैं यह प्रिंट होगा:

 1 2 handler 

ध्यान दें कि यह '3' प्रिंट नहीं करता क्योंकि एक अपवाद फेंका गया था जो उस प्रवाह को बीच में आता है।

Bluebird वादों पर एक नज़र डालें:

ध्यान दें कि मुझे इसके अलावा अन्य कई पुस्तकालय नहीं मिले हैं जो फेंक दिया अपवादों को ठीक से संभालते हैं। उदाहरण के लिए, jQuery के आस्थगित, नहीं – "असफल" हैंडलर को अपवाद कभी नहीं मिलेगा जो एक 'फिर' हैंडलर को फेंक दिया, जो मेरी राय में एक सौदा ब्रेकर है

मैंने इस बारे में हाल ही में http://snmaynard.com/2012/12/21/node-error-handling/ पर लिखा था। संस्करण 0.8 में नोड की एक नई सुविधा डोमेन है और आपको त्रुटि प्रबंधन के सभी रूपों को एक आसान प्रबंधन प्रपत्र में संयोजित करने की अनुमति है। आप अपने पद में उनके बारे में पढ़ सकते हैं

आप अपने अयोग्य अपवादों को ट्रैक करने और ई-मेल, चॅटरूम के माध्यम से अधिसूचित होने या बिना किसी अपवाद के अपवाद (मैं बग्सनाग के सह-संस्थापक) के लिए बनाई गई टिकट की तरह कुछ भी उपयोग कर सकते हैं।

एक उदाहरण जहां एक try-catch का प्रयोग उपयुक्त हो सकता है जब forEach लूप का उपयोग करना यह तुल्यकालिक है लेकिन साथ ही आप केवल आंतरिक क्षेत्र में रिटर्न स्टेटमेंट का उपयोग नहीं कर सकते हैं इसके बजाय एक कोशिश और पकड़ने के दृष्टिकोण का उपयोग उचित क्षेत्र में त्रुटि ऑब्जेक्ट वापस करने के लिए किया जा सकता है। विचार करें:

 function processArray() { try { [1, 2, 3].forEach(function() { throw new Error('exception'); }); } catch (e) { return e; } } 

यह ऊपर @ बाल्टन द्वारा वर्णित दृष्टिकोणों का एक संयोजन है

मैं सिर्फ यह जोड़ना चाहूंगा कि Step.js लाइब्रेरी हमेशा अगले चरण फ़ंक्शन में इसे पारित करके अपवादों को संभालने में मदद करती है। इसलिए आप पिछले चरण के रूप में एक फ़ंक्शन के रूप में हो सकते हैं जो किसी भी पिछले चरणों में त्रुटियों की जांच करता है। यह दृष्टिकोण आपकी त्रुटि प्रबंधन को सरल रूप से सरल कर सकता है।

नीचे जिथूब पृष्ठ से एक उद्धरण है:

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

इसके अलावा, आप स्क्रिप्ट को अंजाम देने के लिए स्टेप का उपयोग कर सकते हैं, ताकि अंतिम चरण के रूप में साफ-सफाई वाले भाग को प्राप्त कर सकें। For example if you want to write a build script in Node and report how long it took to write, the last step can do that (rather than trying to dig out the last callback).

After reading this post some time ago I was wondering if it was safe to use domains for exception handling on an api / function level. I wanted to use them to simplify exception handling code in each async function I wrote. My concern was that using a new domain for each function would introduce significant overhead. My homework seems to indicate that there is minimal overhead and that performance is actually better with domains than with try catch in some situations.

http://www.lighthouselogic.com/#/using-a-new-domain-for-each-async-function-in-node/

If you want use Services in Ubuntu(Upstart): Node as a service in Ubuntu 11.04 with upstart, monit and forever.js

Catching errors has been very well discussed here, but it's worth remembering to log the errors out somewhere so you can view them and fix stuff up.

​Bunyan is a popular logging framework for NodeJS – it supporst writing out to a bunch of different output places which makes it useful for local debugging, as long as you avoid console.log. ​ In your domain's error handler you could spit the error out to a log file.

 var log = bunyan.createLogger({ name: 'myapp', streams: [ { level: 'error', path: '/var/tmp/myapp-error.log' // log ERROR to this file } ] }); 

This can get time consuming if you have lots of errors and/or servers to check, so it could be worth looking into a tool like Raygun (disclaimer, I work at Raygun) to group errors together – or use them both together. ​ If you decided to use Raygun as a tool, it's pretty easy to setup too

 var raygunClient = new raygun.Client().init({ apiKey: 'your API key' }); raygunClient.send(theError); 

​ Crossed with using a tool like PM2 or forever, your app should be able to crash, log out what happened and reboot without any major issues.