Node.js + Express.js अनुप्रयोगों के लिए सिद्धांतों को संभालने में त्रुटि?


177

ऐसा लगता है कि त्रुटि रिपोर्टिंग / हैंडलिंग अन्य रूपरेखाओं की तुलना में Node.js + Express.js अनुप्रयोगों में अलग तरह से की जाती है । क्या मैं यह समझने में सही हूं कि यह निम्नानुसार काम करता है?

ए) उन्हें आपके कॉलबैक फ़ंक्शन के मापदंडों के रूप में प्राप्त करके त्रुटियों का पता लगाएं । उदाहरण के लिए:

doSomethingAndRunCallback(function(err) { 
    if(err) {  }
});

बी) अगले (गलत) कॉल करके MIDDLEWARE में त्रुटि की रिपोर्ट करें । उदाहरण:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}

C) त्रुटि को आरओयूटीईएस में त्रुटि को फेंक कर रिपोर्ट करें । उदाहरण:

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

डी) हैंडल app.error के माध्यम से अपने खुद के त्रुटि हैंडलर कॉन्फ़िगर करके त्रुटियों () या का उपयोग सामान्य कनेक्ट त्रुटि हैंडलर। उदाहरण:

app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});

क्या ये चार सिद्धांत Node.js + Express.js अनुप्रयोगों में सभी त्रुटि हैंडलिंग / रिपोर्टिंग के लिए आधार हैं?

जवाबों:


183

Node.js में त्रुटि हैंडलिंग आमतौर पर प्रारूप ए) है। अधिकांश कॉलबैक पहले तर्क या के रूप में एक त्रुटि ऑब्जेक्ट वापस करते हैंnull

Express.js मिडलवेयर का उपयोग करता है और मिडलवेयर सिंटैक्स B) और E का उपयोग करता है (नीचे उल्लेख किया गया है)।

यदि आप मुझसे पूछते हैं तो C) बुरा अभ्यास है।

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

आप आसानी से उपरोक्त को फिर से लिख सकते हैं

app.get('/home', function(req, res, next) {
    // An error occurs
    next(err);
});

मिडलवेयर सिंटैक्स एक में मान्य है get अनुरोध ।

डी के लिए के रूप में)

(07:26:37 PM) tjholowaychuk: app.error 3.x में हटा दिया गया है

टीजे ने बस इसकी पुष्टि की app.error ई के पक्ष में पदावनत किया गया है

इ)

app.use(function(err, req, res, next) {
  // Only handle `next(err)` calls
});

कोई भी मिडलवेयर जिसकी लंबाई 4 (4 आर्ग्युमेंट) है, को एरर मिडलवेयर माना जाता है। जब कोई कॉल next(err)कनेक्ट होता है, तो त्रुटि-आधारित मिडलवेयर कॉल करता है।


11
धन्यवाद! भविष्य में जो कोई भी इस पर आ सकता है, उसके लिए ऐसा लगता है कि "मेथड ई" के लिए परम का क्रम वास्तव में इरेट, रीक, रेस, नेक्स्ट (रीक, रेस, नेक्स्ट, इर के बजाय) है।
क्लिंट हैरिस

9
तो यह बहुत अच्छा लग रहा है, लेकिन एक समस्या जो मैं देख रहा हूं वह यह है कि कुछ त्रुटियां आपके द्वारा बताए गए त्रुटि हैंडलर के लिए अपना रास्ता कभी नहीं बनाती हैं, और केवल एक प्रक्रिया द्वारा पकड़ा जा सकता है। ('uncaughtException', fn) हैंडलर। पारंपरिक ज्ञान यह है कि ऐसा होने दें और फॉरएवर या ऐप को पुनः आरंभ करने पर निर्भर करें, लेकिन यदि आप ऐसा करते हैं, तो आप एक फ्रेंडली एरर पेज को कैसे लौटाते हैं?
पॉल

1
@chovy इसके अलावा, सिर्फ एक फी। त्रुटि हैंडलर को फेंकने / अगली त्रुटि के बाद ऐप को देना होगा। यदि यह पहले है, तो यह त्रुटि नहीं पकड़ेगा।
ली ओलय्यवर

3
अगला (गलत) अनिवार्य रूप से एक त्रुटि फेंकने का एक्सप्रेस संस्करण है, आपको स्पष्ट रूप से इसे अपने स्वयं के मिडलवेयर के भीतर कॉल करना होगा, हालांकि
कोडेनिन्जा

1
@qodeninja एक्सप्रेस में इस पद्धति को एक सर्वोत्तम अभ्यास माना जाता है।
डेविड ओलिवरोस

11

जॉयंट के लोगों ने इस पर वास्तव में व्यावहारिक सर्वोत्तम प्रथाओं को प्रकाशित किया है । किसी भी Node.js डेवलपर के लिए एक लेख अवश्य पढ़ें।



महान लेख, जॉयंट के अद्यतन दस्तावेज़ को इंगित करने के लिए लिंक तय किया।
Stephbu

2
लेख बुरा नहीं है: लेकिन बहुत अधिक पाठ और पर्याप्त उदाहरण नहीं यह वास्तविक पेशेवरों के लिए एक लेख है
गर्ड

3

पहले पैरामीटर क्यों?

Node.js की अतुल्यकालिक प्रकृति के कारण, उपयोगकर्ता -पैरामीटर Node.js त्रुटि हैंडलिंग के लिए एक कन्वेंशन के रूप में पहला पैरामीटर-एर्स-इरेट अच्छी तरह से स्थापित हो गया है । यह अतुल्यकालिक है क्योंकि:

try {
    setTimeout(function() {
        throw 'something broke' //Some random error
    }, 5)
}
catch(e) {
   //Will never get caught
}

इसलिए कॉलबैक के पहले तर्क के बजाय त्रुटियों को केवल अतुल्यकालिक रूप से पारित करने के अलावा उन्हें फेंकने के लिए बहुत ही समझदार तरीका है।

ऐसा करने का परिणाम unhandled exceptionयह होगा कि जिस तरह से यह लग रहा है, इसका मतलब है कि आवेदन को अपनी उलझन की स्थिति से बाहर निकालने के लिए कुछ भी नहीं किया गया था।

अपवाद, वे क्यों मौजूद हैं

हालांकि, यह ध्यान देने योग्य है कि लगभग सभी Node.js का हिस्सा इवेंट-एमिटर हैं और एक अपवाद को फेंकना एक निम्न-स्तरीय घटना है जिसे सभी घटनाओं की तरह संभाला जा सकता है:

//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
    console.error("calm down...", err)
});

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

डोमेन - घटनाओं को तार्किक रूप से समूहीकृत करना

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

ES6

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

Koa (TJ Holowaychuck द्वारा लिखित, Express.js का एक ही मूल लेखक) ध्यान देने योग्य रूप से ऐसा करता है। यह yieldब्लॉक बनाने के लिए ES6 स्टेटमेंट का उपयोग करता है, जो लगभग सिंक्रोनस दिखाई देते हुए, सामान्य नोड अतुल्यकालिक फैशन में संभाला जाता है:

app.use(function *(next) {
    try {
        yield next;
    } 
    catch (err) {
        this.status = err.status || 500;
        this.body = err.message;
        this.app.emit('error', err, this);
    }
});

app.use(function *(next) {
    throw new Error('some error');
})

यह उदाहरण यहाँ से बेशर्मी से चुराया गया था ।

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