Hoy · Hoja de ruta
- 1. Aprende: Qué es un middleware, cómo se escribe uno propio y cómo se centralizan los errores.
- 2. Haz: Añade registro de peticiones y un único punto de tratamiento de errores.
- 3. Comprueba: Ninguna ruta tiene ya su propio
try/catch.
Antes de empezar · 5 minutos, sin apuntes
- ¿Cuántos
try/catchhay repartidos por tus rutas? - Si quisieras registrar el tiempo de cada petición, ¿dónde lo pondrías?
- ¿Qué debe ver el cliente cuando algo se rompe por dentro?
Qué es un middleware
Middleware
Una función que recibe la petición, la respuesta y una tercera función, next. Puede mirar o modificar la petición, puede responder y cortar la cadena, o puede llamar a next para que siga el paso siguiente.
function registrar(peticion, respuesta, next) {
const inicio = Date.now();
respuesta.on("finish", () => {
const ms = Date.now() - inicio;
console.log(`${peticion.method} ${peticion.originalUrl} → ${respuesta.statusCode} (${ms} ms)`);
});
next();
}
app.use(registrar);
Lo que hace útil este ejemplo es dónde se registra: al terminar la respuesta, de modo que el estado y el tiempo ya son conocidos. Una sola declaración cubre además todas las rutas, presentes y futuras.
Un middleware que no responde ni llama a next cuelga la petición
La petición se queda dentro de la cadena, sin avanzar y sin respuesta, hasta que el cliente se cansa. No hay error, no hay traza, no hay nada en los registros. Es el fallo más desconcertante de Express, y siempre es el mismo olvido.
Errores en un solo sitio
app.get("/api/productos/:id", async (peticion, respuesta, next) => {
try {
const producto = await obtener(Number(peticion.params.id));
if (!producto) throw new ErrorNoEncontrado("Producto no encontrado");
respuesta.json(producto);
} catch (error) {
next(error); // se lo pasa al manejador de errores
}
});
// El último de todos, y con cuatro parámetros
app.use((error, peticion, respuesta, next) => {
if (error instanceof ErrorDeValidacion) {
return respuesta.status(400).json({ error: error.message, detalles: error.errores });
}
if (error instanceof ErrorNoEncontrado) {
return respuesta.status(404).json({ error: error.message });
}
console.error(error); // la traza, para ti
respuesta.status(500).json({ error: "Error interno del servidor" });
});
Los cuatro parámetros son lo que distingue a un manejador de errores de un middleware normal: si quitas el next final, Express lo tratará como uno cualquiera y no lo llamará nunca.
La traza es para ti; el mensaje, para quien llama
Devolver al cliente el error completo revela rutas de ficheros, versiones y estructura interna, que es precisamente la información que busca quien intenta atacar un sistema. Tampoco aporta nada a quien solo pretendía consultar un producto.
Registra el detalle en el servidor y responde un mensaje genérico con el estado correcto. Esa es la razón de que el manejador tenga la última palabra sobre qué sale.
Tarea 15 · La cadena completa
- Escribe el middleware de registro con método, ruta, estado y tiempo.
- Escribe uno que rechace cuerpos demasiado grandes.
- Convierte todas tus rutas para que deleguen los errores con
next. - Escribe el manejador de errores central con sus tres casos.
- Comprueba que un fallo interno responde 500 sin filtrar la traza.
- Provoca un middleware sin
nexty observa qué ocurre.
try/catch.Cierre de la semana 5
- Tu servidor está reescrito con Express y se comporta igual.
- Sabes qué pieza sustituye a cada cosa que escribiste a mano.
- El registro y los errores están en un solo sitio.
- El cliente nunca ve una traza.
Ver respuestas
1 · Que la petición se queda colgada sin respuesta ni error.
2 · Cuatro parámetros, empezando por el error.
3 · Porque revela información interna del sistema y no ayuda a quien llama.
Microprueba semanal 5 · 5–10 minutos
Individual, sin IA y sin apuntes.
- Nombra tres problemas del servidor escrito a mano y qué pieza de Express resuelve cada uno.
- ¿Qué ocurre si un middleware no responde ni llama a
next? - ¿En qué se distingue un manejador de errores de un middleware normal?