‫Instructor: En esta lección, implementemos una mejor
‫forma de detectar errores en todas nuestras funciones asíncronas.
‫Entonces, en este momento, en todas
‫nuestras funciones asíncronas, tenemos estos bloques try catch, ¿verdad?
‫Entonces, recuerde cómo agregamos a todas estas funciones de control este intento
‫y luego este bloque de captura, ¿de acuerdo?
‫Y todas tienen esto porque todas
‫son funciones asíncronas y así es
‫como generalmente detectamos los errores dentro de
‫una función asíncrona.
‫Entonces, usando un bloque try catch.
‫Ahora, eso realmente hace que nuestro código se vea desordenado y desenfocado, por
‫lo que el objetivo de este método createTour aquí, por ejemplo,
‫es simplemente ejecutar este código.
‫En realidad, no queremos perder el
‫tiempo con el
‫manejo de errores aquí, por lo que ahora mismo tenemos
‫estos dos bloques adicionales, intente capturar, y
‫con eso viene esta sangría adicional
‫aquí y nuevamente, esto realmente hace que nuestro código no parezca limpio.
‫Realmente no está enfocado.
‫Además, tenemos mucho código duplicado aquí porque
‫en cada uno de estos
‫controladores tenemos un bloque de captura bastante similar.
‫Entonces, en todo esto, todo
‫lo que estamos haciendo es enviar esta respuesta.
‫Y esa respuesta en realidad ni siquiera se
‫enviaría aquí, sino en nuestro middleware global de manejo de errores,
‫recuerde, pero ese es otro tema.
‫Por ahora, lo que estoy
‫tratando de enfocar aquí es que
‫estos bloques de captura de prueba dentro de cada una de nuestras
‫funciones asíncronas no son ideales, así que ahora intentemos solucionarlo.
‫Y la solución es básicamente sacar el bloque try
‫catch de aquí y ponerlo en un nivel
‫superior en otra función.
‫Básicamente, lo que vamos
‫a hacer es
‫crear una función y luego envolver esta función asíncrona en esa función.
‫¿Está bien?
‫Y déjame llamarlo catchAsync.
‫Así que catchAsync, y lo llamo de esta manera
‫porque el objetivo de
‫esta función es simplemente detectar nuestros errores asincrónicos.
‫Tan simple, ¿verdad?
‫Entonces, en esta
‫función catchAsync, pasaremos una función, ¿de acuerdo?
‫Y recuerde, la función que vamos a
‫pasar es básicamente esta.
‫Entonces, ahora que estamos trabajando con este
‫ejemplo, la función que pasaremos a catchAsync es esta
‫función porque aquí es donde queremos
‫detectar los errores asincrónicos.
‫Así que hagámoslo de verdad.
‫Entonces fn, y luego envuelva toda esa función allí.
‫Entonces, a continuación, lo que tenemos que hacer
‫es llamar a esta función aquí.
‫Así que llámelo, y esta función
‫debería recibir solicitud, respuesta y, de hecho, también siguiente.
‫Así que este de aquí también debería tener next y
‫todos los demás,
‫porque recuerde, necesitamos la función next
‫para pasarle el error para que
‫ese error pueda ser manejado
‫en el middleware global de manejo de errores.
‫Entonces, todas estas funciones necesitarán solicitud,
‫respuesta y lo siguiente.
‫Pero dejémoslo para más tarde.
‫Por ahora, centrémonos realmente en nuestro catchAsync aquí.
‫Entonces, esta función aquí que pasamos a async,
‫que ahora se llama fn aquí,
‫es una función asincrónica.
‫Y recuerda que las
‫funciones asincrónicas devuelven promesas, ¿verdad?
‫Y cuando hay un error dentro de
‫una función asincrónica, eso básicamente significa que la promesa es rechazada.
‫Y entonces aquí, donde realmente llamamos a esa función,
‫podemos detectar ese error.
‫Así que lo capturamos aquí, en
‫lugar de atraparlo en el bloque try catch.
‫Entonces captura, y error, y luego siguiente, y pasa el error.
‫Y podemos
‫simplificar esto, pero por ahora eliminemos el bloque try
‫catch aquí, y simplemente concéntrese en esta pieza.
‫Así que esto
‫es todo lo que queremos y ya no necesitamos el
‫bloque try catch, nuevamente, porque ese catch ahora se transfiere básicamente
‫a aquí, a esta línea.
‫Ya no es un bloque
‫de captura, porque aquí es más
‫fácil usar la promesa de que devuelve la función fn.
‫Entonces, nuevamente, esta función fn es esta función, por
‫lo que la que pasamos a catchAsync,
‫y que devolverá una promesa.
‫Y de hecho, noté aquí que
‫esto, por supuesto, debería llamarse catchAsync, ¿de acuerdo?
‫Y luego, esa función
‫que pasamos a catchAsync, esta es, por supuesto, fn.
‫¿Está bien?
‫Entonces el argumento que pasamos allí.
‫Ahora, en realidad, hay dos grandes problemas con la forma
‫en que esto se implementa en este momento
‫y, por lo tanto, de esta manera, realmente no funcionaría en absoluto.
‫Entonces, el primero, esta llamada de función
‫aquí no tiene forma de conocer la solicitud, la respuesta y el siguiente.
‫No los pasamos a catchAsync aquí, por lo que
‫realmente no hay forma
‫de que la función conozca los valores de estos parámetros.
‫Y en segundo lugar,
‫aquí mismo estamos llamando a la función asíncrona.
‫Y para ver esto un poco mejor, eliminémonos
‫por completo de este código.
‫Así que aquí tenemos catchAsync y luego lo llamamos
‫usando paréntesis, por supuesto.
‫Y luego, dentro de catchAsync, también estamos llamando
‫de inmediato a la función fn, y no es
‫así como se supone que funcione.
‫Así que createTour aquí debería ser realmente una función, pero
‫no el resultado de llamar a una función.
‫Pero eso es lo que está sucediendo ahora mismo.
‫Así que ahora mismo se
‫está llamando a catchAsync, que luego llama a esta función aquí, ¿de acuerdo?
‫Y de nuevo, esta función no debería llamarse,
‫sino que debería sentarse aquí y esperar
‫hasta que express la llame.
‫Y Express, por supuesto, lo
‫llamará tan pronto como alguien llegue
‫a la ruta que necesita esta función de control.
‫Entonces, la solución a eso es básicamente hacer que la
‫función catchAsync devuelva otra función que luego se
‫asignará a createTour y para que esa función
‫se pueda llamar
‫más tarde cuando sea necesario.
‫Así que hagámoslo aquí.
‫Así que regresemos una función anónima y recordemos
‫que esta es la función a
‫la que express llamará.
‫Y aquí es donde
‫especificamos solicitud, respuesta y siguiente.
‫En realidad falta la flecha aquí.
‫Y esta bien.
‫Y eso es todo.
‫Esa es nuestra función catchAsync.
‫Solo recuerde cómo dije que
‫podríamos simplificarlo y eso es solo
‫porque, en JavaScript, podemos simplificarlo así, así
‫que todo lo que necesitamos pasar aquí es
‫la función, y luego se llamará automáticamente
‫con el parámetro que recibe esta devolución de llamada.
‫Entonces es lo mismo que escribir a continuación.
‫Así que recapitulemos aquí.
‫Entonces, para deshacernos de nuestros bloques try catch,
‫simplemente ajustamos nuestra función asincrónica
‫dentro de la función catchAsync que acabamos de crear.
‫Esta función devolverá una nueva función anónima,
‫que es
‫esta aquí, que luego se asignará a createTour.
‫Y, básicamente, es esta función aquí
‫la que se llamará tan pronto como
‫se cree un nuevo recorrido utilizando el controlador createTour.
‫Y es por eso que tiene exactamente
‫la misma firma aquí que esta función asincrónica, con solicitud, respuesta y siguiente.
‫Ahora, lo que hará esta función
‫aquí es que llamará a
‫la función que pasamos inicialmente, así
‫que esta aquí,
‫y luego ejecutará todo el código que está allí.
‫Ahora, dado que aquí es una función asincrónica,
‫devolverá una promesa y,
‫por lo tanto, en caso de que haya un error en
‫esta promesa o, en otras palabras, en caso de
‫que sea rechazada, podemos detectar el error que
‫sucedió usando el método de captura que es disponible en todas las promesas.
‫Y al final, es este método de captura aquí
‫el que pasará el error a la siguiente función
‫que luego hará que nuestro
‫error termine en nuestro middleware global de manejo de errores.
‫Así que aquí, esta línea de
‫código, es realmente donde ocurre toda la magia,
‫y esto es, de hecho,
‫lo que nos permite deshacernos del bloque catch que teníamos anteriormente.
‫Y una
‫nota: esto es bastante complicado de entender y en
‫caso de que no esté 100% claro, no
‫se preocupe, no es tan importante.
‫En realidad, se trata de averiguar cómo funciona
‫exactamente el código asincrónico detrás de escena en JavaScript.
‫Así que no se trata tanto de Express o Node. js, esto trata
‫más sobre cómo funciona el código asincrónico.
‫De todos modos, si ahora creamos un nuevo
‫recorrido y ocurre
‫algún error, por ejemplo, de una entrada
‫no válida, entonces ese error, por supuesto, debería detectarse
‫aquí en esta función de
‫captura, y luego se propagará a nuestro middleware de manejo
‫de errores y de modo que uno luego enviará de vuelta
‫la respuesta de error que se espera que recibamos.
‫Y ahora probemos eso.
‫Así que crea un nuevo recorrido.
‫Aquí tenemos el
‫cuerpo, y ahora eliminemos uno de estos campos obligatorios.
‫Está bien.
‫Y eso debería desencadenar un error, así que veamos.
‫Y, de hecho, la validación de nuestro recorrido falló, que es
‫exactamente el mensaje de error
‫que se suponía que íbamos a recibir.
‫Ahora aquí, ve este error interno del servidor 500, que se debe simplemente
‫al hecho de que en este momento
‫el error que se propagó al
‫middleware de manejo de
‫errores no tenía ningún código de estado especificado, por
‫lo que recuerde que nuestro valor predeterminado es 500 y
‫ese es el único que luego fue enviado de vuelta.
‫Y, por supuesto, tenemos que arreglar
‫eso y lo haremos en una conferencia posterior de este curso.
‫Por ahora, lo que importa aquí
‫es que, en primer lugar, nuestra función catchAsync funciona según lo
‫previsto y, en segundo lugar, que el error en realidad se
‫propagó, por lo que fue detectado por nuestro middleware de
‫manejo de errores globales, que luego envió esta respuesta al cliente.
‫Ahora vayamos a exportar esta función de
‫captura a su propio archivo.
‫Así que lo tomaré de
‫aquí y crearé solo otro archivo en
‫nuestra carpeta de utilidades.
‫Así que catchAsync. js.
‫Y hasta aquí, módulo. las exportaciones deberían ser solo esto.
‫Y eso debería funcionar bien.
‫De vuelta en nuestro controlador de
‫viaje, por supuesto, ahora necesitamos importar esta función.
‫Y, como de costumbre, debemos subir una
‫carpeta y luego a nuestra carpeta de
‫utilidades y luego catchAsync.
‫Muy bien, y ahora todo
‫lo que tenemos que hacer es deshacernos de
‫todos estos bloques de captura y envolver todos los manejadores en catchAsync.
‫Así que hagámoslo.
‫Primero envuelva y luego elimine estos bloques.
‫Guárdelo para reformatearlo y aquí vamos.
‫Y ahora es simplemente un proceso de repetir
‫esto hasta que todos los recorridos, o, lo siento,
‫hasta que todos los controladores hayan terminado.
‫Bien, guarde rápido.
‫Este ya está hecho.
‫El siguiente es la actualización.
‫Y solo falta uno más.
‫O en realidad, eso no es cierto.
‫Allí abajo tenemos aún más funciones asincrónicas.
‫Así que nos desharemos de la captura y el intento aquí.
‫Y creo que este es el último.
‫Y sí, de hecho lo es.
‫Muy bien, ahora otra cosa que
‫debemos hacer es agregar junto a todos ellos aquí también.
‫Pero claro, no en mayúsculas.
‫Bueno.
‫Y permítanme seleccionarlos todos aquí para que
‫solo tenga que escribirlos una vez.
‫Y eso se sumaba a todos ellos.
‫Y ahora creo que hemos terminado con esta parte.
‫Probemos de nuevo muy rápidamente, no con este,
‫sino aquí con, no con este
‫también, así que hemos terminado.
‫Y voy a intentar hacer
‫un recorrido pero con una identificación no válida, así que veamos qué sucede aquí.
‫Y de hecho, recibimos nuestro mensaje de
‫error y nuevamente con el código de estado 500,
‫que no es correcto, recuerde,
‫pero nos ocuparemos
‫de eso en un momento posterior.
‫Así que ahora mismo, déjame mostrarte que aquí
‫es de donde viene el 500 porque ahora mismo no hay un
‫código de estado dentro del error
‫que obtenemos porque estos errores,
‫en realidad provienen de Mongoose, por lo que no
‫tenemos forma de
‫agregar un estado. código a estos errores.
‫O en realidad, por supuesto, podríamos hacerlo, pero eso
‫sería aún más confuso y, por lo
‫tanto, encontraremos otra forma más adelante en
‫esta sección.
‫Por ahora, estoy muy contento con el resultado que tenemos
‫aquí y eso es todo para esta conferencia.