Aquí está la estructura de mi aplicación:
- app.js - routes ---- index.js La aplicación ExpressJS crea controladores de errores para entornos de development y production . Aquí hay un fragmento de código de app.js :
app.use('/', routes); // routing is handled by index.js in the routes folder //The following middleware are generated when you create the Express App // catch 404 and forward to error handler app.use(function (req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error.ejs', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); Y dentro de routes/index.js , donde manejo todo el enrutamiento:
var router = express.Router(); router.get('/', function (req, res) { someAsyncFunction(function(err, result) { if (err) throw err; // Handle this error } }); module.exports = router; Quiero que el err se pase a uno de los controladores de errores en lugar de lanzarlo. ¿Cómo puedo hacer esto?
Debe pasarlo a la siguiente devolución de llamada, que suele ser el tercer parámetro en el controlador de ruta
var router = express.Router(); router.get('/', function (req, res, next) { someAsyncFunction(function(err, result) { if (err) { next(err); // Handle this error } } }); module.exports = router; llamar a next(err) permitirá que el error se detecte en un middleware en la cadena con la siguiente firma:
app.use(function (err, req, res, next){ // do something about the err });Referencia: http://expressjs.com/en/guide/error-handling.html
También puede crear una función de middleware para manejar el error en todas las rutas sin copiar el código en todas partes, utilizando funciones de flecha si lo desea.
1) Cree una función const para manejar errores.
o:
const handleErrorAsync = func => (req, res, next) => { func(req, res, next).catch((error) => next(error)); };o
const handleErrorAsync = func => async (req, res, next) => { try { await func(req, res, next); } catch (error) { next(error); } };2) En su enrutador, utilícelo para cada solicitud:
var router = express.Router(); router.get('/req1', handleErrorAsync(async (req, res, next) => { let result = await someAsyncFunction1(); if(result){ // res.send whatever } })); router.post('/req2', handleErrorAsync(async (req, res, next) => { let result = await someAsyncFunction2(req.body.param1); if(result){ // res.send whatever } })); router.post('/req3', handleErrorAsync(async (req, res, next) => { let result = await someAsyncFunction3(req.body.param1, req.body.param2); if(result){ // res.send whatever } })); module.exports = router;3) En el error de manejo de la aplicación principal de su servidor:
// development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error.ejs', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); });De esta manera, puede reutilizar la función de manejo de errores en cualquier ruta. Además, si hay errores no controlados en cualquiera de sus funciones, esto también los detectará.
Intente capturar el manejo de errores tomado de Aquí