El manejo de errores en Express es crucial para crear aplicaciones robustas y predecibles. Permite capturar, procesar y responder a diferentes tipos de errores de manera controlada.
// errorHandler.js
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
this.isOperational = true;
Error.captureStackTrace(this, this.constructor);
}
}
// Middleware de manejo de errores global
const globalErrorHandler = (err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
res.status(err.statusCode).json({
status: err.status,
message: err.message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
};
module.exports = { AppError, globalErrorHandler }; // catchAsync.js - Manejo de errores asíncronos
const catchAsync = (fn) => {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
};
// Ejemplo de uso
const getUsers = catchAsync(async (req, res, next) => {
const users = await User.find();
if (!users.length) {
return next(new AppError('No users found', 404));
}
res.status(200).json({
status: 'success',
results: users.length,
data: { users }
});
}); | Código | Significado | Ejemplos Prácticos |
|---|---|---|
| 200 | OK | Solicitud exitosa |
| 201 | Created | Recurso creado |
| 400 | Bad Request | Datos inválidos o faltantes |
| 401 | Unauthorized | Token inválido o expirado |
| 403 | Forbidden | Sin permisos suficientes |
| 404 | Not Found | Recurso no existente |
| 422 | Unprocessable Entity | Errores de validación |
| 500 | Internal Server Error | Errores no controlados |
// validationMiddleware.js
const { body, validationResult } = require('express-validator');
const validate = (validations) => {
return async (req, res, next) => {
for (let validation of validations) {
const result = await validation.run(req);
if (result.errors.length) break;
}
const errors = validationResult(req);
if (errors.isEmpty()) {
return next();
}
return res.status(400).json({
errors: errors.array()
});
};
};
// Ejemplo de uso
app.post('/usuarios',
validate([
body('email').isEmail().withMessage('Email inválido'),
body('nombre').notEmpty().withMessage('Nombre requerido')
]),
crearUsuario
); const winston = require('winston');
const logger = winston.createLogger({
level: 'error',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'error.log' })
]
});
// Middleware de registro
const errorLogger = (err, req, res, next) => {
logger.error({
message: err.message,
stack: err.stack,
method: req.method,
path: req.path
});
next(err);
}; express-validator