← Node.js: JavaScript fuera del navegador

Sesión 15 · Semana 5

Middleware, registro y errores

Hoy · Hoja de ruta

  1. 1. Aprende: Qué es un middleware, cómo se escribe uno propio y cómo se centralizan los errores.
  2. 2. Haz: Añade registro de peticiones y un único punto de tratamiento de errores.
  3. 3. Comprueba: Ninguna ruta tiene ya su propio try/catch.

Antes de empezar · 5 minutos, sin apuntes

  1. ¿Cuántos try/catch hay repartidos por tus rutas?
  2. Si quisieras registrar el tiempo de cada petición, ¿dónde lo pondrías?
  3. ¿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

  1. Escribe el middleware de registro con método, ruta, estado y tiempo.
  2. Escribe uno que rechace cuerpos demasiado grandes.
  3. Convierte todas tus rutas para que deleguen los errores con next.
  4. Escribe el manejador de errores central con sus tres casos.
  5. Comprueba que un fallo interno responde 500 sin filtrar la traza.
  6. Provoca un middleware sin next y observa qué ocurre.
Objetivo mínimoRegistro funcionando y errores centralizados en un único manejador.
Si lo tienesAñade un identificador único a cada petición y sácalo en los registros y en la respuesta de error.
RetoEscribe un envoltorio que capture los errores de las rutas asíncronas sin repetir 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.

  1. Nombra tres problemas del servidor escrito a mano y qué pieza de Express resuelve cada uno.
  2. ¿Qué ocurre si un middleware no responde ni llama a next?
  3. ¿En qué se distingue un manejador de errores de un middleware normal?
---