Node.js सबसे अच्छा अभ्यास अपवाद हैंडलिंग


755

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

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

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


11
बिना किसी अपवाद के नहीं होना चाहिए। यदि वे एक ऐसे प्रोग्राम का उपयोग करते हैं जो आपके दुर्घटनाग्रस्त होने पर आपके पूरे आवेदन को फिर से शुरू करता है (हमेशा के लिए, पर्यवेक्षक)
Raynos

116
बिना किसी अपवाद के हमेशा ऐसा हो सकता है जब तक कि आप अपने अतुल्यकालिक कोड के हर टुकड़े को अंदर नहीं डालते हैं try .. catch, और यह भी जांच लें कि यह आपके सभी
Dan

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

8
@EugeneBeresovksy Dan सही है, लेकिन यह इस तथ्य को नहीं बदलता है कि जब अनक्रेडिसेप्शन होता है तो केवल सुरक्षित विकल्प ऐप को पुनरारंभ करना है। दूसरे शब्दों में, आपका ऐप क्रैश हो गया है और ऐसा कुछ भी नहीं है जो आप कर सकते हैं या इसके बारे में करना चाहिए। यदि आप कुछ नया करना चाहते हैं, तो नया, और अभी भी प्रायोगिक, v0.8 डोमेन सुविधा लागू करें ताकि आप क्रैश को लॉग कर सकें और अपने क्लाइंट को 5xx प्रतिक्रिया भेज सकें।
ostergaard

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

जवाबों:


736

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

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

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

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

    // 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है , तो त्रुटि होती है, यदि कोई त्रुटि नहीं होती है, तो errहै 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)

सुरक्षित रूप से "कैचिंग" त्रुटियां

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

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

    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...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असिंक्रोनस कोड के साथ संयोजन के साथ काम करना चाहते हैं , तो नोड 7.4 या अधिक चलने पर आप async/awaitअपने अतुल्यकालिक कार्यों को लिखने के लिए मूल रूप से उपयोग कर सकते हैं ।

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

    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

5
धन्यवाद रेन्नोस, अद्यतन। क्या आपके पास कोई स्रोत है जो बुराइयों की व्याख्या करता है try catch? जैसा कि मैं सबूत के साथ वापस प्यार करता हूँ। सिंक उदाहरण भी तय किया।
बालुप्टन

2
यह उत्तर अब मान्य नहीं है। डोमेन इस समस्या को हल करता है (नोड द्वारा अनुशंसित)।
गेब्रियल लामास

5
त्रुटि से निपटने के लिए @balupton त्रुटियाँ डाली जानी चाहिए। उन्हें निश्चित रूप से टाला नहीं जाना चाहिए। उनके बारे में ऐसा कुछ नहीं है जो ऐप के निष्पादन को तोड़ता है या कुछ और। जावा और अधिकांश अन्य आधुनिक भाषाओं में अपवादों के लिए उत्कृष्ट समर्थन है। यहाँ कुछ विकृत पोस्टों को पढ़ने के बाद मेरा एकमात्र निष्कर्ष यह है कि लोग उन्हें बहुत अच्छी तरह से नहीं समझते हैं और इसलिए उनसे डरते हैं। भय अoubनी शंका। यह बहस कम से कम 20 साल पहले अपवादों के पक्ष में तय की गई थी।
enl8enmentnow

22
अब डोमेन io.js द्वारा पदावनत कर दिए जाते हैं : " यह मॉड्यूल लंबित है। एक प्रतिस्थापन एपीआई को अंतिम रूप दिए जाने के बाद, यह मॉड्यूल पूरी तरह से पदावनत हो जाएगा ... उपयोगकर्ता जो पूरी तरह से कार्यक्षमता प्रदान करते हैं, जो डोमेन प्रदान करते हैं, वे समय के लिए इस पर भरोसा कर सकते हैं लेकिन भविष्य में एक अलग समाधान के लिए पलायन करने की उम्मीद करनी चाहिए। "
टिमोथी गु

5
डोमेन एपीआई अब पदावनत है ? वे एक प्रतिस्थापन एपीआई का उल्लेख करते हैं - किसी को पता है कि यह कब निकलेगा, और यह कैसा दिखेगा?
उपराष्ट्रपति

95

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


Node.JS त्रुटि से निपटने के सर्वोत्तम अभ्यास


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

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

अन्यथा: Node.JS कॉलबैक शैली, फ़ंक्शन (इरेटा, प्रतिक्रिया), अनौपचारिक कोड के लिए एक आशाजनक तरीका है, जो आकस्मिक कोड, अत्यधिक नेस्टिंग और अजीब कोडिंग पैटर्न के साथ त्रुटि से निपटने के मिश्रण के कारण होता है।

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

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 वें स्थान पर)

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


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

TL; DR: कोड को देखने में काफी सामान्य है जो त्रुटियों को स्ट्रिंग के रूप में या एक कस्टम प्रकार के रूप में फेंकता है - यह त्रुटि हैंडलिंग तर्क और मॉड्यूल के बीच अंतर को जटिल करता है। चाहे आप किसी वादे को अस्वीकार करते हैं, अपवाद को फेंक देते हैं या त्रुटि फेंकते हैं - 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 रैंक "Node.JS त्रुटि")

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


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

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

अन्यथा: त्रुटि सामने आने पर आप हमेशा एप्लिकेशन को पुनरारंभ कर सकते हैं, लेकिन ~ 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);
});

ब्लॉग उद्धरण : "अन्यथा आप राज्य को जोखिम में डालते हैं" (ब्लॉग डीबग करने योग्य से, कीवर्ड "Node.JS अनकैप्ड" के लिए 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 रैंक "Node.JS त्रुटि हैंडलिंग")

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


नंबर 5: स्वैगर का उपयोग करते हुए दस्तावेज़ एपीआई त्रुटियाँ

टीएल; डीआर: अपने एपीआई कॉलर्स को बताएं कि कौन सी त्रुटियां बदले में आ सकती हैं ताकि वे दुर्घटनाग्रस्त हुए बिना सोचे समझे इन्हें संभाल सकें। यह आमतौर पर स्वैगर की तरह REST API डॉक्यूमेंट फ्रेमवर्क के साथ किया जाता है

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

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

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


नंबर 6: किसी अजनबी के शहर में आने पर प्रक्रिया को शान्तिपूर्वक बंद करें

TL; DR: जब कोई अज्ञात त्रुटि होती है (एक डेवलपर त्रुटि, सबसे अच्छा अभ्यास नंबर # 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 जे जैसे परिपक्व लॉगिंग टूल का एक सेट, त्रुटि खोज और समझ को गति देगा। तो कंसोल के बारे में भूल जाओ।

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

कोड उदाहरण - कार्रवाई में विंस्टन लकड़हारा

//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. कई विन्यास गंतव्य धाराओं के लिए अनुमति देता है। उदाहरण के लिए, आप एक फ़ाइल में ट्रेस लॉग लिख रहे होंगे, लेकिन जब कोई त्रुटि सामने आती है, तो उसी फ़ाइल पर लिखें, फिर त्रुटि फ़ाइल में और उसी समय एक ईमेल भेजें ...


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

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

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

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

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


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


30

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

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


4
+1 लिंक उपयोगी है, धन्यवाद। मैं अभी भी सबसे अच्छा अभ्यास रहा हूँ और के Node.js संदर्भ में "सुंदर पुनः आरंभ" का अर्थ
मोमो

इस संदर्भ में "ग्रेसफुल रिस्टार्ट" की मेरी समझ अनिवार्य रूप से वही होगी जो नोपेन्कोप सुझाव देती है: प्रक्रिया को मरने दो, और जो कुछ भी चल रहा है उसे पहले ही शुरू कर दो।
इल्का

उस लिंक के लिए बहुत बहुत धन्यवाद! वास्तव में उपयोगी!
सथेशजम

यह एक बेहतरीन जवाब है। हालाँकि मैं आपके पहले उदाहरण में एक त्रुटि वापस करने के बारे में असहमत हूँ। रिटर्निंग Errorरिटर्न वैल्यू पॉलीमॉर्फिक बनाता है जो फ़ंक्शन के शब्दार्थ को अनावश्यक रूप से पिघला देता है। इसके अलावा, 0 से डाइविंग पहले से ही देकर जावास्क्रिप्ट में नियंत्रित किया जाता है Infinity, -Infinityया NaN, मूल्यों जहां typeof === 'number'। उनके साथ जांच की जा सकती है !isFinite(value)। सामान्य तौर पर मैं अनुशंसा करूंगा कि किसी फ़ंक्शन से कोई त्रुटि न लौटाए। एक विशेष गैर-बहुरूपी मूल्य w / सुसंगत शब्दार्थ को फेंकने या वापस करने के लिए कोड की उपयुक्तता और रखरखाव के संदर्भ में बेहतर है।
22:15 पर wprl

लिंक टूट गया है। downforeveryoneorjustme.com/debuggable.com
केव

13

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

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

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

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' प्रिंट नहीं करता है क्योंकि एक अपवाद फेंक दिया गया था जो उस प्रवाह को बाधित करता है।

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

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


जावास्क्रिप्ट में उचित वादे विनिर्देश को वादे / ए + के रूप में जाना जाता है। आप यहां कार्यान्वयन की सूची देख सकते हैं: github.com/promises-aplus/promises-spec/blob/master/… । ध्यान दें कि एक नंगे वादे / ए + व्यवहार में अनुपयोगी है - वादे / ए + अभी भी खुद को हल करने के लिए पुस्तकालयों के लिए व्यावहारिक समस्याओं का एक बहुत छोड़ देता है। हालाँकि आपके द्वारा दिखाए जाने वाले त्रुटि प्रचार जैसी बिल्कुल आवश्यक चीजें, नियतात्मक निष्पादन आदेश और स्टैक ओवरफ्लो से सुरक्षा की गारंटी है।
एस्लेइजा


11

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

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


2
डोमेन मॉड्यूल अब आधिकारिक तौर पर पदावनत हो गया है। nodejs.org/api/domain.html
मैटसिडोर

3

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

नीचे github पृष्ठ का एक उद्धरण है:

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

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


3

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

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

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


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

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

1

कुछ समय पहले इस पोस्ट को पढ़ने के बाद मैं सोच रहा था कि क्या यह एक एपीआई / फ़ंक्शन स्तर पर अपवाद हैंडलिंग के लिए डोमेन का उपयोग करना सुरक्षित था। मैं उनके द्वारा लिखे गए प्रत्येक async फ़ंक्शन में अपवाद हैंडलिंग कोड को सरल बनाने के लिए उनका उपयोग करना चाहता था। मेरी चिंता यह थी कि प्रत्येक फ़ंक्शन के लिए एक नए डोमेन का उपयोग करने से महत्वपूर्ण ओवरहेड का परिचय होगा। मेरा होमवर्क इंगित करता है कि कम से कम ओवरहेड है और यह प्रदर्शन वास्तव में कुछ स्थितियों में कोशिश पकड़ने के साथ डोमेन के साथ बेहतर है।

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


1

कैचिंग एरर की यहां बहुत अच्छी तरह से चर्चा की गई है, लेकिन त्रुटियों को कहीं बाहर लॉग इन करना याद रखना उचित है ताकि आप उन्हें देख सकें और सामान को ठीक कर सकें।

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

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

अगर आपको बहुत सी त्रुटियाँ और / या सर्वरों की जाँच करने में समय लगता है, तो यह एक उपकरण की तरह देखने लायक हो सकता है, जैसे कि Raygun (अस्वीकरण, मैं Raygun में काम करता हूँ) एक साथ समूह त्रुटियों के लिए - या उन दोनों का एक साथ उपयोग करें। यदि आपने Raygun को एक उपकरण के रूप में उपयोग करने का निर्णय लिया है, तो इसे सेटअप करना बहुत आसान है

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

PM2 या हमेशा की तरह एक उपकरण का उपयोग करके पार किया गया, आपका ऐप क्रैश करने में सक्षम होना चाहिए, जो भी हुआ और बिना किसी बड़े मुद्दों के रिबूट करें।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.