Juan Carlos Leandro Diaz Zegarra
500 Internal Server Error
Juan Agustin Di Pasquo
Reinaldo Mendoza
Como metieron ese gato ahi?
¿Cómo implementar middlewares para manejo de errores en JavaScript?
Los middlewares son una herramienta poderosa al desarrollar aplicaciones en JavaScript. Entre sus múltiples usos, se destacan los middlewares para manejo de errores, que ayudan a capturar, formatear y gestionarlos de manera uniforme. En esta guía aprenderás cómo implementar y utilizar middlewares que capturen y gestionen errores de forma global en tu aplicación.
¿Cómo configurar y comenzar con middlewares de error?
La implementación de un middleware para manejo de errores comienza por organizar el código en una estructura limpia. Es recomendable crear una carpeta dedicada exclusivamente para los middlewares, asegurando una separación adecuada del código.
Crear una carpeta para middleware:
Implementar el primer middleware:
errors.js dentro de la carpeta de middlewares.logErrors. Esta función capturará el error y lo desplegará en la consola. A continuación se presenta un ejemplo de cómo se vería esta función:function logErrors(err, req, res, next) { console.error(err.stack); next(err); }
errorHandler, que formatea el error en un objeto JSON y lo envía al cliente. Aquí se muestra cómo podría implementarse:function errorHandler(err, req, res, next) { res.status(500).json({ message: err.message, stack: err.stack, }); }
¿Cuáles son los pasos para integrar middlewares de error en la aplicación?
Para que estos middlewares funcionen efectivamente, deben integrarse después de definir las rutas (routing) de la aplicación.
require para importar las funciones logErrors y errorHandler. Aquí cómo podrías importarlas:const { logErrors, errorHandler } = require('./middlewares/errors');
app.use() para incluir los middlewares en tu aplicación express:app.use(logErrors); app.use(errorHandler);
logErrors debe ejecutarse antes que errorHandler. Puedes verificar el orden mediante logs en la consola.¿Cómo manejar errores de forma explícita en el routing?
Para detectar y gestionar errores de manera efectiva, es necesario realizar algún manejo de errores a nivel de las rutas.
try-catch. De esta manera, los errores se pueden capturar y enviar explícitamente a través de next(err) para que sean manejados por los middlewares:app.get('/productos/:id', async (req, res, next) => { try { // lógica de obtención de producto } catch (err) { next(err); // Envía el error a los middlewares de manejo de error. } });
¿Cómo mejorar el tratamiento de errores?
Una buena práctica es utilizar códigos de estado HTTP para comunicar correctamente la naturaleza del error al cliente y evitar asignar siempre un error 500. Por ejemplo:
404: Producto no encontrado.409: Conflictos que indican alguna restricción de negocio que no se cumple.401 o 403: Falta de permisos.Asegúrate de adaptar la gestión de errores para utilizar los códigos de estado más adecuados, maximizando la claridad para el cliente y facilitando el mantenimiento.
Implementar middlewares para errores es un paso esencial hacia una aplicación robusta y profesional. Sigue explorando estas técnicas avanzadas para optimizar tu desarrollo en JavaScript. ¡Continúa aprendiendo y perfeccionando tus habilidades en cada clase!
Espero les sirvan mis apuntes: Crear middleware de tipo error:
//Creamos función que nos hará llegar a un middleware de tipo error: function logErrors(err, req, res, next) { console.error(err); //mostrar el error en servidor para poder monitorearlo next(err); //importante para saber que se esta enviando a un middleware de tipo error, si no tiene el error dentro entonces se esta mandando a uno normal } // Crear formato para devolverlo al cliente que se complementa con la función anterior: function errorHandler(err, req, res, next) { //así no se utilice next en el código se debe poner aqui, ya que un middleware de error tiene los cuatro parámetros res.status(500).json({ //indicar que el error es estatus 500 Internal Server Error message: err.message, //mostrar al cliente el mensaje de error stack: err.stack, //mostrar info del error }) } module.exports = { logErrors, errorHandler }; //exportarlo como modulo
Implementar middleware:
// Importar middleware const { logErrors, errorHandler } = require('./middlewares/errorHandler'); //importar las funciones que se uilizarán
Los middlewares de tipo error siempre deben ir después de definir el routing.
routerApi(app); // Utilizamos los middleware. Siempre deben ir después del routing: app.use(logErrors); app.use(errorHandler);
Es importante el orden en que se coloquen porque es el orden en que se ejecutarán. En este caso el logErrors es el único con un next, por lo tanto, si se colocará el errorHandler antes, ahí terminaría el proceso.
Además de lo anterior, el error se debe capturar de forma explicita en el router:
// Encontrar un producto por su id: router.get('/:id', async (req, res, next) => { //se agrega el next try { const { id } = req.params; const product = await service.findOne(id); res.json(product); } catch (error) { next(error); //se agrega el next para atrapar de forma explicita el error con el middleware } });
Juan Carlos Leandro Diaz Zegarra
500 Internal Server Error
Juan Agustin Di Pasquo
Reinaldo Mendoza
Como metieron ese gato ahi?
Alba Montilva
Importantísimo el manejo de errores con sus respectivos status dependiendo del error.
Samuel Martínez Hernández
Para complementar tu aporte 😊
HTTP response status codes - HTTP | MDN HTTP Status Codes
Mauricio Gonzalez Falcon
Gracias por el aporte!
Bryan Gama Solórzano
Juan Camilo Muñoz Bedoya
Gracias por el aporte, llevaba un rato comparando el código y no entendía la diferencia.
Enrique Ruvalcaba
Buen aporte, así se evita poner trycatch en cada controller
Diana Patricia Bautista Otálora
El middleware de manejo de errores se define al final, después de otras llamadas de rutas y app.use(); por ejemplo:
Mauricio Ruiz
"Si estuvieras trabajando con typescript esto no ocurriría". Punto para Typescript! ❤️
Erick Alejandro Graterol Barico
¿No les recuerda estos middleware a el tipo de dato de listas enlazadas ? tienes un dato que pasa un puntero al siguiente y asi ...
Irwing Khalisser Naranjo Brito
Nicolas Molina
ProfesorRealmente no veo error evidente en código que nos compartes, pero que parece raro que en tu flujo no hay un lanzamiento de error y la app se rompe, ¿Nos puedes compartir tu repo?
Felix Torres Javier Antonio
a mi me había salido un error así, lo que hice fue quitar el async, intenta quitarlo de tu función find
Andy Cevallos
Yo que vengo de otros lenguajes, veo a los Middlewares como un interceptor. En donde toma la petición http (Caso de Uso) hace algo con eso, y la procesa o descarta.
👽 Quizás este equivocado, pero lo veo así.
Mario Javier Serrano Bula
Importante: Los middlewares de error deben ejecutarse después de definir el routing. De no ser así no serán capturados (No funcionará).
Jose Alberto Reyes Quevedo
Yo tuve problemas con el error middleware, no lo estaba tomando.
hasta que me di cuenta que era un problema con la firma
y encontre esto en la documentación
Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.
siempre hay que agregar los cuatro parámetros aunque no se usen
Jherom Chacon
Mi error handler:
Julio Emiliano Garza Jiménez
Yo parando la clase para revisar como podria hacer handling de los diferentes status de errores y despues de romperme la cabeza, sigo viendo el video y me doy cuenta que el profe lo reconoce y dice que lo vamos a trabajar...
Oier Solabarrieta Egues
Esto de los middlewares me esta volando la cabeza!! 🤯 Creo que es porque son algo bastante abstracto que Express maneja internamente. Sin embargo, me parece una funcionalidad muy útil de este framework, no se a ustedes.
Vianey Vargas
Entonces los Middleware funcionan casi como interceptors ?
Nicolas Molina
ProfesorHola, si es correcto es una forma de interceptar las peticiones y con eso ver si lo dejas o no pasar al siguiente paso.
Alessandra Amicarella
Por que los middlewares de error deben ir al final de las rutas?
Luzan Muga
Es para asegurarte solamente que el error sea capturado correctamente :) si el middleware estuviera antes que las rutas y alguna ruta lanzara un error hay probabilidad de que el middleware de error no atrape la excepción generada dentro de las rutas.
Diego Reyes Cabrera
El profe no puso los middlewares despues de los routes? No se supone que nunca deberian ser llamados esos middlewares?
Nicolas Molina
ProfesorSi realmente si se pusieron en la línea 22 y 23 en el minuto 5:29, si es a lo que te refieres?
app.use(logErrors); app.use(errorHandler);
Diego Reyes Cabrera
@nicobytes Si, y la funcion "routerApi" es llamada en la linea 19. Crei que todos los middlewares debian ser colocados antes de asignar una ruta, incluso los error middlewares.
Francisco Fabian Montaño López
Para la ejecución de middlewares en Express.js, se mencionaron algunas consideraciones importantes:
next(), la ejecución se detiene.Estas prácticas te ayudarán a gestionar mejor los errores y mejorar la experiencia de tu API.
Obed Paz
Me recuerdan a los interceptores de Angular.
Sergio Andrés Bolaños Penagos
Se me hacen muy similares a las promesas
El problema por el que no funcionaba el middleware por defecto es porque la función es asíncrona.
Buscando un poco encontré que Express por defecto no pasa los errores asíncronos a los middleware de error, por lo que había que capturar el error y pasarlo al next en cada función de routing, como se hace en la clase. Pero eso debería hacerse en cada función controller, haciéndose repetitivo. Encontré este paquete que agrega a express la forma de manejar los errores asíncronos, así el middleware funcionará como esperábamos.
npm install express-async-errors
Solo debemos importarlo en el index.js y la función de routing quedará como estaba.
require("express-async-errors");
Hola, tuve un problema, traté de capturar los errores de la misma manera en el método find pero no me funcionó.
Esta en mi ruta:
// get all users router.get('/', async (req, res, next) => { try { const users = await service.find(); res.json(users); } catch (error) { next(error); } });
Y este es el error que estoy tratando de inducir:
async find () { return new Promise((resolve, reject) => { setTimeout(() => { resolve(resetea(this.users)); }, 1000); }); }
Pero me retornar un:
[nodemon] app crashed ......
Nota: en los otros métodos me funciona