node handling error node.js express middleware

node.js - handling - El controlador de errores de middleware Express 4 no se llama



node js error handling (1)

El problema es que los controladores de errores siempre deben estar al final de la pila de aplicaciones. Esto significa que puede mover el controlador de errores de su middleware a su app.js y usarlos después de sus necesidades (app.use () ) o incluir sus rutas antes de su middleware.

Para ciertas páginas tengo manejo personalizado de errores 500, 404 y 403 en mi aplicación. Así, por ejemplo, después de una consulta de base de datos fallida, iría:

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

o

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

En mi middleware tengo un manejador de errores:

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

El problema es que el controlador de errores nunca se llama, en su lugar, la pila de llamadas de error se imprime en el navegador. Quiero que el controlador rinda una página de error personalizada.

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())); });

rutas.js

module.exports = function(app){ app.get(''/'', require(''./views/'').index); app.get(''/blog'', require(''./views/blog'').index); app.get(''/blog/:slug'', require(''./views/blog'').getBySlug); app.route(''/report/:slug'') .get(require(''./views/report/'').index) .post(require(''./views/report/'').doReport); // Very long file with tons of routes. Simplified version.

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 }); };