2015-04-17 16 views
17

नहीं कहा जा रहा है कुछ पृष्ठों के लिए मेरे कस्टम में 500, 404 और 403 त्रुटि हैंडलिंग है। तो एक असफल डेटाबेस क्वेरी के बाद उदाहरण के लिए मुझे जाना चाहते हैं:एक्सप्रेस 4 मिडलवेयर त्रुटि हैंडलर को

return next({status: 404, message: 'Record not found'}); 

या

return next(new Error('Bad things have happened')}); 

मेरी मिडलवेयर में मैं एक त्रुटि हैंडलर है:

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

समस्या है कि त्रुटि हैंडलर कभी नहीं कहा जाता है, बजाय त्रुटि कॉलस्टैक ब्राउज़र में मुद्रित किया जा रहा है। मैं हैंडलर को कस्टम त्रुटि पृष्ठ प्रस्तुत करना चाहता हूं।

app.js

var express = require('express') 
    , app = express() 
    , swig = require('swig') 
    , config = require('./lib/config') 
    , env = process.env.NODE_ENV || 'development' 
    , path = require('path'); 

config.configure(env); 

app.engine('html', swig.renderFile); 
app.set('view cache', false); 

swig.setDefaults({ 
    cache: config.get('swigCache') 
}); 

app.set('view engine', 'html'); 
app.set('views', __dirname + '/lib/views'); 

require('./lib/util/swig'); 
require('./lib/initialisers/mongodb')(); 
require('./lib/initialisers/aws')(); 
require('./lib/middleware')(app); // first load middleware 
require('./lib/routes')(app); // then routes 

var server = app.listen(config.get('port'), function() { 
    console.info('config: ' + JSON.stringify(config.getCurrent())); 
    console.info('NODE_ENV: ' + env); 
    console.info('server running: ' + JSON.stringify(server.address())); 
}); 

routes.js

middleware.js

var express = require('express') 
    , app = express() 
    , path = require('path') 
    , logger = require('morgan') 
    , cookieParser = require('cookie-parser') 
    , bodyParser = require('body-parser') 
    , passport = require('passport') 
    , session = require('express-session') 
    , mongoStore = require('connect-mongo')(session) 
    , compression = require('compression') 
    , favicon = require('serve-favicon') 
    , config = require('./config') 
    , flash = require('connect-flash') 
    , multer = require('multer') 
    , csrf = require('csurf'); 

module.exports = function(app) { 

    app.use(bodyParser.urlencoded({ extended: false })) 
    app.use(bodyParser.json()); 
    app.use(cookieParser()); 
    app.use(csrf({ cookie: true })); 
    app.use(express.static(path.join(__dirname, config.get('staticContentPath')), { 
     maxAge: (60 * 60 * 24) * 1000 
    })); 

    app.use(session({ 
     resave: true, 
     saveUninitialized: true, 
     secret: 'da755fc0-6882-11e4-9803-0800200c9a66', 

     cookie: { 
      maxAge: 24 * 60 * 60 * 1000 // 24 hrs 
     }, 

     store: new mongoStore({ 
      url: config.getMongoConn() 
     }) 
    })); 

    app.use(logger('dev')); 
    app.use(flash()); 

    /** 
    * 301 redirects 
    */ 
    app.use(function(req, res, next) { 

     var host = req.get('host'); 

     // AWS IP --> http 
     if (host == 'xx.xxx.xxx.xxx') { 
      return res.redirect(301, config.get('url') + req.originalUrl); 
     } 

     // AWS origin --> http 
     if(host == 'xxx-xxx-xxx-xxx-xxx.ap-southeast-2.compute.amazonaws.com'){ 
      return res.redirect(301, config.get('url') + req.originalUrl); 
     } 

     // www --> http 
     if (/^www\./.test(host)) { 
      host = host.substring(4, host.length); 
      return res.redirect(301, req.protocol + '://' + host + req.originalUrl); 
     } 

     // Trailing slash --> http 
     if (req.path.substr(-1) == '/' && req.path.length > 1) { 
      var query = req.url.slice(req.path.length); 
      return res.redirect(301, req.path.slice(0, -1) + query); 
     } 

     next(); 
    }); 

    // Delete expired Mongo sessions from DB 
    app.use(function (req, res, next) { 
     req.session._garbage = new Date(); 
     req.session.touch(); 
     next(); 
    }); 

    /** 
    * Setting Cache control header for Ajax requests to 30 minutes 
    */ 
    app.use(function (req, res, next) { 

     if(req.xhr){ 
      res.header('Cache-Control', 'max-age=' + 1800 + ', public'); 
     } 

     next(); 
    }); 

    app.use(compression()); 

    app.use(
     multer({ 
      dest: config.get('uploads').folders.temp 
     }) 
    ); 

    app.use(passport.initialize()); 
    app.use(passport.session()); 
    var initPassport = require('./passport/init'); 
    initPassport(passport); 

    app.use(function (req, res, next) { 

     res.locals = { 
      root : 'http://' + req.headers.host, 
      sitename : require('./config').get('sitename'), 
      config: config.get('env'), 
      url : config.get('url'), 
      user : req.user, 
      flash : req.flash() 
     }; 

     next(); 
    }); 

    app.use(function (err, req, res, next) { 

     if (err.code !== 'EBADCSRFTOKEN'){ 
      return next(err); 
     } 

     if(req.xhr){ 
      return res.ok({payload: null}, '403 invalid csrf token'); 
     } 

     // TODO handle CSRF token errors here 
     res.status(403); 
     res.send('form tampered with') 
    }); 

    // This is never called when throwing errors like 
    // next(new Error('some error') or 
    // next({status: 500, message:'server error'}); 
    app.use(function (err, req, res, next) { 
     console.error(err.stack); 
     // render an error page 
    }); 
}; 
+0

आपको "app.use (function (err, req, res, next) {" दो बार घोषित किया गया है। क्या res.status (403) वापस आ रहा है? –

+0

लेकिन यह तब तक (त्रुटि) देता है जब तक कि यह न हो खराब सीएसआरएफ टोकन त्रुटि। यहां तक ​​कि अगर मैं कोड के उस ब्लॉक को लेता हूं और केवल एक ऐप.यूज (फ़ंक्शन (त्रुटि, रिक, आरएस, अगली) है जिसे इसे कभी नहीं कहा जाता है। – ChrisRich

+9

मार्गों को मिडलवेयर के रूप में वर्गीकृत किया जाता है, क्योंकि सब कुछ एक ही उपयोग करता है राउटर। त्रुटि हैंडलर हमेशा आपके कॉल स्टैक के अंत में होना चाहिए। उन्हें अपनी फ़ाइल में जोड़ें और इसे अपने मार्गों के बाद जोड़ें। [दस्तावेज़ों को संभालने में त्रुटि] (http://expressjs.com/guide/error-handling.html) यदि आप अपने मिडलवेयर त्रुटि हैंडलर को रखना चाहते हैं तो आपको अपने मार्गों के बाद भी जोड़ना होगा। –

उत्तर

24

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

+2

डांग! मैंने मध्यवर्ती शब्दशः और pla इसे एप प्रारंभिक और मार्ग परिभाषा के बीच में रखा गया। – JohnnyQ

+0

मुझे ओपी के संदर्भ में मार्गों के नीचे पूरी तरह से मार्गों को स्थानांतरित करने में बस एक समस्या का एहसास हुआ। 'बॉडीपार्सर्स 'और' यूआरएलएनकोडर्स 'काम नहीं करेंगे, मार्गों को इन 2 बिचौलियों के बीच रखा जाना चाहिए। – JohnnyQ

+0

गोटो! इस दिन के साथ इस तरह से संघर्ष किया गया: https://stackoverflow.com/questions/46929330/express-async-await-error-handling - पोस्ट करेगा मेरी समस्या क्या थी और यह कैसे हल हुआ। – npr

संबंधित मुद्दे