Trabajo con Windows y tuve un ligero problema con la variable de entorno en el archivo errorHandlres.js
if(config.dev)//siempre retornaba true
Haciéndome imposible visualizar el cambio de funcionalidad, de el errorHandler, en las pruebas con postman al cambiar de entorno(dev to prod).
Resulta que en Windows ocurre lo siguiente:
// En package.json"start":"set NODE_ENV=production && node index"//en errorHandlers.jsconsole.log(process.env.NODE_ENV==='production')//falseconsole.log(process.env.NODE_ENV.trim()==='production')//true
En windows al parecer inserta caracteres especiales a la variable de entorno. Por ello, realicé los siguientes cambios:
package.json:
"dev":"set DEBUG=app:* && set NODE_ENV=development && nodemon index",
config/index.js
dev: process.env.NODE_ENV.trim()!=='production',
Para usar el entorno de desarrollo seteé la variable de entorno "development" para que al usar trim() no me marque error por asignar un método a un undefined.
Gracias por la explicacion!
Gracias bro, me sirvio
Si alguien no consigue que le salga el error capturado correctamente en modo production sólo tiene que hacer estos cambios:
++package.json++:
"start": " set NODE_ENV=production && node index"
Muchas gracias!!!, no encontraba la solución a ese problema :(
El middleware es como este meme, cumple la condición o haz lo que dice el middleware y te deja pasar a la logica de la ruta. Usando next()
Usamos 2 middleware
Para hacer console.log del error
Para enviar el json con el error
Podria bastar con solo 1
Es por clean code que utiliza dos.
Uno para la consola del desarrollador, y otro para el response de la API, que debe tener su propia lógica y podría crecer en complejidad.
Dato: El orden en el que ponemos los middlewares en este caso importa muchísimo.
Estamos poniendo los middlewares de error después de las rutas porque cuando se crea el error en la ruta pasa al catch y ese catch tiene un callback next() que le pasa el error al siguiente middleware.
El siguiente middleware es logErrors que igual tiene un callback next() que le envía el error al siguiente middleware.
Podemos comprobar que si invertimos el orden de los middlewares y ponemos _errorHandler antes que logErrors en el index después de las rutas vemos que no funcionará el middleware logErrors porque el middleware errorHandler no está pasándole el error a un siguiente middleware por medio del callback next()
En Windos al parecer para ejecutar npm run start, debe ir esto en el package.json:
Ojo, el espacio inexistente entre la palabra producction y && es muy importante!!
Middleware
Un Middleware es una capa intermedia que intercepta la información de algo, un middleware se define por defecto con una función del siguiente formato:
function(req,res,next){next()}
Donde:
req es un httpRequest() con la información de la petición
res es un httpResponse() con la respuesta de la petición
next es un callback de la siguiente función a llamar
Para definir un middleware que reciba un error, sólo se le agregaría un argumento con el error
Utilización del middleware
Express es una infraestructura web de direccionamiento y middleware que tiene una funcionalidad mínima propia: una aplicación Express es fundamentalmente una serie de llamadas a funciones de middleware.
Las funciones de middleware son funciones que tienen acceso al objeto de solicitud (req), al objeto de respuesta (res) y a la siguiente función de middleware en el ciclo de solicitud/respuestas de la aplicación. La siguiente función de middleware se denota normalmente con una variable denominada next.
Las funciones de middleware pueden realizar las siguientes tareas:
Ejecutar cualquier código.
Realizar cambios en la solicitud y los objetos de respuesta.
Finalizar el ciclo de solicitud/respuestas.
Invocar la siguiente función de middleware en la pila.
Si la función de middleware actual no finaliza el ciclo de solicitud/respuestas, debe invocar next() para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada.
Una aplicación Express puede utilizar los siguientes tipos de middleware:
Middleware de nivel de aplicación
Middleware de nivel de direccionador
Middleware de manejo de errores
Middleware incorporado
Middleware de terceros
Puede cargar middleware de nivel de aplicación y de nivel de direccionador con una vía de acceso de montaje opcional. También puede cargar una serie de funciones de middleware a la vez, lo que crea una subpila del sistema de middleware en un punto de montaje.
Ayudaaa! alguien sabe porque el query me da undefined? Por lo tanto al momento de postear la informacion Mongo me tira error. Pero si le hardcodeo los datos si los postea. Mi problema es que esta partecita de codigo me da undefined
router.post("/",asyncfunction(req, res, next){// const { body: movie } = req; //esto me da undefinedconst movie ={title:"Pelicula de prueba"};try{const createdMovieId =await moviesService.createMovie({ movie }); res.status(201).json({data: createdMovieId,message:"movie created",});}catch(err){next(err);}});```
Tendrías que verificar que estás haciendo el post hacia la API correctamente, es decir, que sí sea por post, que no haya typos en el endpoint y que estés mandando como application/json.
También asegúrate que sí tienes la línea de app.use(express.json()) en el index de tu servidor.
Si me faltaba la linea de app.use(express.json()) para que parseara el body. Con eso se soluciono, muchas gracias!
El orden de los middleware importa
¿el orden en como se agregan los middlewares despues de las rutas, es el orden en como se ejecutan?
Sí en efecto. Creo que esta explicación no fue explicita al respecto durante la clase pero tu suposición es correcta. Es un stack de middlwares como una tubería.Con next() se pasa al siguiente nivel. SI no se pone next() no se pasa al siguient middleware y en ese sentido el orden en que se agregan en la pila si influye en la ejecución. Si se envia una respuesta los middlewares que esten despúes de lanzar una petición nunca se van a ejecutar por lo que también es importante tener esto en cuenta.
En el siguiente link hay una muy buena explicación sobre el uso de los distintos middlewares en express Utilización del middleware
Si cuando corren el servidor no diferencia si está en producción o en desarrollo, veriquen su package.json. El comando 'start' debe estar así:
Comparto por si alguno llega a tener el mismo error que yo trabajando con Windows 10.
Al definir las variables de entorno en los scripts dev y start como lo hizo el profe el programa no toma las variables, dejandolas undefined. Lo pude resolver quitando el "set" y los "&&". Me quedaron asi:
[nodemon] starting `node index index.js`/mnt/c/xampp/htdocs/backend-con-node/movies-api/node_modules/express/lib/application.js:210thrownewTypeError('app.use() requires a middleware function')^TypeError: app.use() requires a middleware function at Function.use(/mnt/c/xampp/htdocs/backend-con-node/movies-api/node_modules/express/lib/application.js:210:11) at Object.<anonymous>(/mnt/c/xampp/htdocs/backend-con-node/movies-api/index.js:20:5) at Module._compile(internal/modules/cjs/loader.js:1133:30) at Object.Module._extensions..js(internal/modules/cjs/loader.js:1153:10) at Module.load(internal/modules/cjs/loader.js:977:32) at Function.Module._load(internal/modules/cjs/loader.js:877:14) at Function.executeUserEntryPoint[as runMain](internal/modules/run_main.js:74:12) at internal/main/run_main_module.js:18:47[nodemon] app crashed - waiting for file changes before starting...
He revisado todo el código y está como el profesor lo señaló. No logró entender porqué pasa ese error.
Si alguien tiene alguna idea del origen de ese error, se lo agradezco.
Hola revisa la linea /mnt/c/xampp/htdocs/backend-con-node/movies-api/index.js:20:5. Sin embargo es difícil diagnosticar asi, comparte el repositorio y te ayudo a revisar
Si el next se llama sin el error no va caer en el próximo filtro.
Saludos
A que se si declaro el lanzamiento del error antes de llamada asincrona, me retorna una pila mas completa del error, pero en su mayoría relacionada con los modules de node.?
Colocando el throw new Error después de la llamada asincrona
Error:Error getting movies
at /home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/routes/movies.js:34:13 at process._tickCallback(internal/process/next_tick.js:68:7)
Colocando throw new Error una linea antes de la llamada asíncrona
Error:Error getting movies
at /home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/routes/movies.js:33:13 at Layer.handle[as handle_request](/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/layer.js:95:5) at next(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/route.js:137:13) at Route.dispatch(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/route.js:112:3) at Layer.handle[as handle_request](/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/layer.js:95:5) at /home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/index.js:281:22 at Function.process_params(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/index.js:335:12) at next(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/index.js:275:10) at Function.handle(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/index.js:174:3) at router(/home/alejandro/Escritorio/EscuelaJS/CursoBackendNodeJS/movies-api/node_modules/express/lib/router/index.js:47:12)
Como tienes tu código?
me muestra el mismo error, ya sea en modo productivo o desarrollo .. y el estatus que me envia es el 500