El curso de Express. js: módulo 10: registro y manejo de errores | Shivendra Raghuvanshi | Skillshare

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

El curso de Express. js: módulo 10: registro y manejo de errores

teacher avatar Shivendra Raghuvanshi, Lead Developer and Online Teacher

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      2:28

    • 2.

      Introducción: registro y manejo de errores

      3:23

    • 3.

      Manejo de errores de selección de servidores

      3:24

    • 4.

      Error en el middleware en Express

      4:32

    • 5.

      Elimina los bloqueos de intento y captura

      6:42

    • 6.

      Uso del módulo de errores asyncos de Express

      3:13

    • 7.

      Errores de registro

      9:47

    • 8.

      Registro en MongoDB

      3:46

    • 9.

      Excepciones no atrapadas

      5:03

    • 10.

      Rechazos no manejados

      7:39

    • 11.

      Extraer rutas

      4:40

    • 12.

      Extraer la lógica de registro

      2:08

    • 13.

      Extraer la lógica de la base de datos

      4:30

    • 14.

      Extraer la lógica de configuración

      4:49

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

5

Estudiantes

--

Proyecto

Acerca de esta clase

El módulo 10: registro y manejo de errores se trata de crear aplicaciones de backend fiables y mantenibles con Express.js. Aprenderás a identificar, registrar y manejar errores de manera eficiente, para que tu aplicación se mantenga robusta y segura bajo cualquier circunstancia. Este módulo también cubre la habilidad esencial de organizar tu base de código mediante la extracción de la lógica crítica en módulos separados y reutilizables.

Lo que aprenderás

  • Maneja los errores de selección de servidores con gracia.
  • Domina el uso del middleware de errores en Express.js.
  • Simplifica el manejo de errores con Express Async Errors.
  • Registra errores en la consola, los archivos e incluso MongoDB para el seguimiento y la depuración.
  • Aborda las excepciones no detectadas y los rechazos no manejados.
  • Extrae rutas, registro, bases de datos y lógica de configuración en componentes modulares para una base de código más limpia.

Conoce a tu profesor(a)

Teacher Profile Image

Shivendra Raghuvanshi

Lead Developer and Online Teacher

Profesor(a)
Level: Intermediate

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Bienvenido de nuevo al Módulo diez, registro y manejo de errores de la serie de cursos Express JS. Mi nombre es Shawn Ragawnhi, Tú guía para A lo largo de los años, he construido aplicaciones escalables y robustas para diversas industrias, y en esta clase, te ayudaré a abordar uno de los aspectos más críticos del desarrollo de backend, el registro y los errores de manejo Uno de mis momentos de mayor alegría fue cuando diseñé un sistema de registro que redujo tiempo de depuración para un cliente en un 60% El día de hoy, te mostraré cómo lograr resultados similares. En este módulo, nos enfocaremos en identificar y manejar errores de manera eficiente en Express s, simplificando el manejo de errores con herramientas como errores asíncronos Express, registro de errores en múltiples destinos como archivos y MongoDB para como archivos y MongoDB A continuación, manejar excepciones no detectadas y rechazos no manejados para garantizar la estabilidad de la aplicación Y finalmente, extraeremos y organizaremos partes clave de su aplicación que es el registro de rutas y configuración para una base de código limpia y mantenible Esta clase es para desarrolladores que desean construir aplicaciones Express Jas robustas y mantenibles Si has completado los módulos anteriores, estás listo para sumergirte. Conocimientos básicos de JavaScript no Jas y express es todo lo que necesitas para empezar. Al dominar el manejo de errores y el registro, mejorará significativamente la confiabilidad de sus aplicaciones También ahorrarás incontables horas depurando, convirtiéndote en un desarrollador más eficiente y valioso Finalmente, para el proyecto, construirás un amante personalizado para manejar registros en múltiples transportes Eso es Console Files y Manga DB. Y luego refaccionarás la aplicación Fair Wheels extrayendo validación de alegría y la lógica del servidor en módulos separados Estas tareas prácticas solidificarán su comprensión del manejo de errores y la modularización Este módulo es un cambio de juego para tus habilidades de desarrollo de backend Vamos a sumergirnos y hacer que sus aplicaciones sean más robustas que nunca. Nos vemos en la primera conferencia, comencemos. 2. Introducción: registro y manejo de errores: En nuestra implementación actual de la app de Fairwee, hemos asumido un mundo ideal donde todo funciona No obstante, en el mundo real, siempre hay errores inesperados. Por ejemplo, es posible que nuestra conexión con Mongo Deb se desprenda por cualquier razón Entonces, como práctica recomendada, debe contar para estas situaciones inesperadas y manejarlas correctamente, lo que significa que debe enviar un mensaje de error adecuado al cliente y registrar la excepción en el servidor. Entonces, más adelante, puedes mirar el registro y ver cuáles son algunos problemas que están sucediendo con frecuencia y cómo puedes mejorarlos. Así que permítanme demostrar un escenario del mundo real donde muere nuestro servidor Mongo EV Entonces aquí en la terminal, se puede ver que estoy ejecutando la aplicación con Nord mod. Y aquí está mi otra ventana terminal donde estoy dirigiendo Mongo Damon Se trata de un servicio en segundo plano que está escuchando en el puerto 27017 Y aquí en Cartero, tengo una pestaña abierta para enviar un get request api CR Entonces cuando enviamos esta solicitud, obtenemos una respuesta de 200. Hermoso. Ahora, de vuelta en la terminal Mongo DB, voy a detener este proceso Así que déjame abrir una nueva ventana Power Show y escribir top services name MongoDB. Y eso es todo. Nuestro servidor Mongo DV ahora está cerrado. Veamos qué sucede cuando envías esta solicitud una vez más. Entonces esto está colgando ahí. Después de unos segundos, vamos a ver un mensaje de error en el terminal donde estamos ejecutando la aplicación. Bien, así que aquí está el mensaje de error. Error de selección del servidor de Mongo, selección SRO agotó el tiempo de espera después, entonces tenemos una selección de servidor de valor dinámico, tiempo de espera S. Y aquí está el error real Entonces, por defecto, cuando te conectas a Mongo DB, si no se puede establecer la conexión, controlador MongoDB intentará reconectarse tres veces con Si te desplazas hacia abajo hasta la parte inferior de la página, C, nuestra aplicación se estrelló Eso significa que salimos del proceso con el código uno. Ahora en esta demostración en particular, apagué el MongAivServer, así que realmente no importaría si este proceso está en vivo Pero imaginemos en un escenario del mundo real, nuestro servidor Manga Divi va a caer por, digamos, 1 minuto, y luego va a volver después de 1 minuto Con la implementación actual, nuestro proceso de nodo terminará y no podrá atender a ningún otro cliente incluso después de Mongo Divi resta Entonces este es un problema y uno muy grande. Entonces necesitamos manejar adecuadamente estos escenarios, y eso es lo que vamos a aprender en esta sección. 3. Manejo de errores de selección de servidores: Ahora demos el primer paso para manejar este error correctamente. Entonces, siempre que vea un error de selección del servidor, eso significa que el cliente Manga B no puede conectarse a ningún servidor en la implementación de Mangaib Esto sucede por diversas razones como anillos de conexión incorrectos, problemas de red, mala configuración del servidor o incompatibilidad de versiones Tenga en cuenta que este error ocurrió cuando intentamos obtener datos de la API del automóvil Entonces vayamos a nuestro módulo de autos. Este es el manejador para obtener la lista de autos. Entonces aquí tenemos una promesa que se devuelve aquí. Estamos esperando eso, pero en ninguna parte de este código, tenemos un bloque try cache para manejar promesas rechazadas. Esta implementación es lo mismo que conseguir una promesa, llamar entonces, pero no llamar al efectivo para manejar los errores. Entonces, si estás usando la sintaxis prometida, siempre debemos llamar a caché para manejar excepciones. Si estás usando una sincronización y Aviate, siempre debes tener r bloques de caché Entonces aquí, necesitamos poner este código en un tri bloque como este y luego agregar el bloque de caché donde obtenemos el error. Ahora aquí necesitamos enviar una respuesta adecuada al cliente. Entonces responde ese estatus. Usamos el código de error 500, lo que significa error interno del servidor. Entonces algo falló en el servidor, no sabemos qué. Y luego mandar un mensaje como si algo fallara. Ahora, técnicamente, aquí también deberíamos registrar la excepción, pero vamos a ver eso más adelante. Así que vamos a mejorar esta aplicación paso a paso. Ahora, veamos cómo funciona esta nueva implementación. Entonces de vuelta en la terminal, voy a iniciar Mangaibi primero porque si no lo iniciamos y ejecutamos la aplicación, mira, no podemos conectarnos a Entonces inicialmente, quiero estar conectado con Mangaib y luego quiero dejar esa conexión en algún lugar en el medio Entonces detengamos esta aplicación. Ahora de vuelta a la ventana de la terminal. Vamos a ejecutar inicio nombre de servicio Mangaib. Ahora vamos a ejecutar nuestra aplicación de ruedas justas. Bien, conectado a Manga DV. Voy a iniciar este proceso. Así que de nuevo, nombre de servicio superior Manga DV. Entonces aquí en Post MD, voy a enviar una solicitud para el punto final de autos. Esto va a tomar 30 segundos, así que voy a pausar la grabación y volver. Bien. Esto es lo que obtenemos. Error interno del servidor 500. Y este es nuestro mensaje. Ahora bien, si nos fijamos en la ventana de terminal de nuestra aplicación, ya no verá ese error de selección del servidor, que resultó en la terminación de este proceso. 4. Error en el middleware en Express: Entonces, en la última conferencia, dimos el primer paso para manejar correctamente los errores. Pero hay un problema en la implementación actual. Digamos que mañana decidimos cambiar el mensaje que enviamos al cliente. Con la implementación actual, tenemos que pasar por cada manejador de rutas donde usamos este bloque Trcche y modificar Entonces en una situación del mundo real, aquí vamos a registrar el error. Nuevamente, si en el futuro, decidimos cambiar la forma en que registramos el error tenemos que volver a varios manejadores de ruta y hacer ese cambio Entonces queremos mover esta lógica para manejar errores a algún lugar central. Entonces, en el futuro, queremos hacer un cambio en la lógica para manejar errores. Hay un solo lugar que necesitamos modificar. Así que vamos al punto índice g. Aquí es donde estamos registrando nuestras funciones de middleware En Express, tenemos un tipo especial de función de middleware llamada error Registramos esa función de middleware después de todas las funciones de middleware existentes Entonces aquí llamamos app that US y pasamos una función de middleware con tres parámetros, request response, y next Pero también agregamos un cuarto argumento aquí al frente. Esa es la excepción o error que atrapamos en otro lugar de la aplicación. Ahora en esta función, agregamos toda la lógica para manejar errores en nuestra aplicación. Así que de vuelta a los autos Js. Voy a cortar esta lógica desde aquí y pegarla aquí. Ahora, de vuelta a los autos Js una vez más. Aquí en este bloque de caché, queremos pasar el control a nuestra función de middleware de manejo de errores Entonces agregamos un nuevo parámetro aquí, siguiente. Y como saben, llamamos next para pasar el control a la siguiente función de middleware en procesamiento de solicitudes Aquí en el bloque de caché, llamamos siguiente y pasamos este error como argumento. Ahora bien, porque en index o Js, registramos esta función después de todas las funciones de middleware existentes, cuando llamemos siguiente, terminaremos aquí Y el error que pasemos será el primer argumento a esta función. Ahora con esta nueva implementación, tenemos un solo lugar para manejar errores. Entonces, si quieres hacer cambios en el futuro, solo regresamos y modificamos esta función. En una aplicación del mundo real, la lógica para registrar la excepción o los errores puede tener varias líneas de largo. No queremos añadir todos los detalles en index dot Js. Entonces en index o Js, solo queremos hacer orquestación. Queremos hacer un arreglo de alto nivel. Los detalles deben ser encapsulados en un módulo diferente. Entonces voy a mover esta función, esta función de middleware a un módulo separado Así que aquí atrás, tenemos esta carpeta de middleware. Vamos a agregar un nuevo archivo aquí, error punto Js. Volviendo al índice Js, voy a obtener esta función aquí y en error Js, establecer exportaciones de módulo a esta función. Entonces ahora separamos los detalles del manejo de errores en un módulo separado, y esto da como resultado una mejor separación de las preocupaciones. En index o Js en la parte superior, necesitamos cargar este módulo. Así const error. Establecimos esto para que requiera. Después vamos un nivel hasta la carpeta middleware, y descargamos el Y finalmente, aquí, llamamos app dot g y pasamos nuestra función de manejo de errores. Tenga en cuenta que no estoy llamando a esta función. Sólo estoy pasando una referencia a esta función. Así que ahora nuestra aplicación tiene un mejor diseño. No obstante, en cast o Js, tenemos este bloque try cache, y como puedes ver, tenemos que repetir esto en cada manejador de rutas en nuestra aplicación Tenemos que agregar este error de caché, y aquí deberíamos llamar a siguiente. Esto es repetitivo. Entonces, en la próxima conferencia, voy a mostrarles cómo mejorar esta implementación. 5. Elimina los bloqueos de intento y captura: En este manejador de rutas, tenemos un bloque try cache para manejar errores El problema es que terminaremos repitiendo este bloque try cache en cada manejador de ruta individual Esto agrega mucho ruido a nuestro código y hace que sea más difícil enfocarse en la lógica real de cada ruta. Es solo una distracción. Idealmente, queremos mover esta lógica de manejo de errores de alto nivel en otro lugar a una sola función que podamos reutilizar en todas las rutas. Déjame mostrarte cómo podemos hacer esto. Primero, crearemos una función reutilizable llamada middleware asincrónico Esta función servirá como plantilla. Incluirá el bloque tri cache que necesitamos, pero lo haremos flexible que pueda adaptarse a diferentes manejadores de ruta Entonces la función tomará como argumento un manejador de ruta como este Dentro del bloque tr, llamaremos a ese manejador Si algo sale mal, el bloque de caché pasará el error siguiente función de middleware De esta manera, la única parte que cambia para cada ruta es una lógica específica en el manejador Todo lo demás permanece igual. Bien, definamos este middleware asincrónico. Entonces esta función se verá algo así. Toma un controlador de ruta como argumento dentro, envolvemos el manejador en un bloque de caché tr Si el controlador arroja un error, el bloque de caché llama a continuación con la excepción Ahora usemos este middleware en nuestra ruta. Entonces, en lugar de escribir ese bloque de caché tr directamente en el controlador de ruta, pasamos esta función al middleware asincrónico Este middleware se encargará del manejo de errores por nosotros Así que no necesitamos este siguiente parámetro, el bloque tr, y el bloque de caché. Entonces nuestro código de ruta se vuelve mucho más limpio. Ahora, mira esta función ASN, la función anónima que estamos pasando como manejador de rutas Finalmente, queremos pasar esta función ASN como argumento a esta nueva función Ahora, debido a que handler es una función ASN, deberíamos esperarla Y como hemos usado esperar aquí, también deberíamos marcar esta función como AS. Ahora hay un pequeño tema que debemos abordar. Al llamar al manejador dentro de Async Middleware, necesitamos pasar la respuesta de solicitud y los siguientes parámetros necesitamos pasar la respuesta de solicitud y los siguientes parámetros. Pero aquí está la trampa. Esos objetos no están definidos en ningún lugar en un middleware de sincronización Entonces, ¿cómo se obtiene acceso a estos parámetros? Bueno, para resolver esto, necesitamos entender cómo funciona el express. Entonces aquí, cuando definimos una ruta router punto get, digamos nueva ruta. Aquí pasamos una función de manejador de ruta que toma tres parámetros, request response, y next, y va a una gráfica de código Entonces no llamamos a esta función nuestras ventas. En cambio, pasamos una referencia a esta función, y Express se encarga de llamarla y pasar los argumentos requeridos. Eso es respuesta de solicitud y siguiente en tiempo de ejecución. Pero en nuestra implementación actual, estamos llamando directamente a Async Middleware No es así como Express espera que funcione. Tenemos que hacer un pequeño cambio aquí. Entonces convertiremos esta función de middleware asíncrono en una función Entonces, en lugar de llamarlo directamente, haremos que devuelva una nueva función. Esta función devuelta actuará como el manejador de ruta real al que Express puede llamar Por lo que esta nueva función devuelta aceptará la respuesta de solicitud, y siguiente como parámetros. Y dentro, llamará al manejador original, pasamos a Middleware asincrónico, pasando por request response y next Ahora, cuando Express llama a esta función devuelta, proporcionará los objetos necesarios. Eso es respuesta de solicitud y siguiente, y todo va a funcionar a la perfección. Con la configuración, hemos movido tricchblock al middleware asincrónico Esto significa que nuestros manejadores de rutas están ahora súper limpios. Estamos esperando la llamada al manejador, así que necesitamos marcar la función de llamada, que es esta función como asíncrona Y ya no necesitamos aplicar este asincrónico aquí ya que en esta función en middleware asincrónico en ninguna parte estamos esperando una promesa, simplemente estamos devolviendo una simplemente estamos devolviendo ¿Bien? Por último, hagamos reutilizable el middleware asincrónico Entonces lo moveremos a un módulo separado aquí en nuestra carpeta de middleware Vamos a crear un nuevo archivo llamado Js asíncrono. Déjame cortar el código para Async Middleware desde aquí y pegarlo aquí Por último, lo exportaremos como exportaciones de pensamiento de módulo, y configuramos esto en un motor divertido. De vuelta aquí en Casta Js, simplemente cargue este artículo intermedio Async Entonces en la parte superior, const middleware asincrónico. Configuramos esto para requerir entonces la carpeta middleware y Y eso es todo. Ahora puede usar este middleware en cualquier manejador de rutas a través Entonces, con este enfoque, tu núcleo se vuelve más limpio, más enfocado y más fácil de mantener. 6. Uso del módulo de errores asyncos de Express: En la última conferencia, definimos esta función de middleware asincrónico Ahora bien, mientras esta función de middleware asíncrono resuelve el problema de los bloques repetitivos tr cach, el problema que tenemos es que tenemos que recordar llamarlo cada Y esto también hace que nuestro cable sea un poco ruidoso. Entonces en esta conferencia, voy a mostrarles un enfoque diferente. Vamos a usar un módulo NPM, y este módulo parcheará a nuestros manejadores de ruta en Entonces, cuando enviamos una solicitud a este punto final, ese módulo envolverá nuestro código de manejador de ruta dentro de algo como esto Déjame mostrarte cómo funciona eso. Así que abre un terminal e instala Express, errores asincrónicos. Vamos a instalar esto. Ahora, vayamos a index o Js Necesitamos cargar este módulo cuando se inicie la aplicación. Entonces tendremos un requerimiento de errores asíncronos expresos. Eso es todo lo que tenemos que hacer. No hay que obtener el resultado y almacenarlo en una constante. Ahora de vuelta en autos o JS, podemos eliminar la llamada a Aync Middleware y volver a nuestra implementación original de manejador de rutas, que es mucho De igual manera, voy a eliminar la segunda llamada al middleware asincrónico Y por último, en la parte superior, voy a quitar también la declaración requerida. Ahora probemos esto y asegurémonos de que esté funcionando correctamente. Así que de vuelta en la terminal, voy a ejecutar nuestra aplicación Fairwheels Ahora, en carteros, voy a conseguir todos los autos. Entonces ese punto final está funcionando. Ahora voy a parar a Manga DB. Entonces aquí en la terminal Manga Di B, detengamos esto con el nombre de servicio superior Manga DB luego enviemos otra solicitud al servidor para que vuelva a enviar. Esto va a tomar un poco de tiempo. Bien, aquí está la respuesta que esperábamos un error 500 con este mensaje. Entonces esto verifica que este módulo que instalamos correctamente movió el control de un manejador de ruta a nuestra función de manejo de errores Por lo que se puede ver el uso errores de Express Aync es muy, muy fácil Y este es mi enfoque sugerido para manejar errores asíncronos en manejadores de rutas expresas Sin embargo, si este módulo no funciona para su aplicación por cualquier razón, entonces necesita volver a este otro enfoque y usar la función de middleware asincrónico 7. Errores de registro: Este es nuestro middleware de error. Ahora, como les dije antes, en cada aplicación empresarial, necesitamos registrar las excepciones que se arrojan en la aplicación. Así que después volvemos, miramos el registro y veremos cuáles son las áreas de la aplicación que podemos mejorar. Entonces en esta conferencia, voy a presentarles una biblioteca maderera muy popular llamada Winston Entonces aquí está el Winston en NPM. La versión actual es 3.17. Y como pueden ver, ha habido 13 millones de descargas semanales. Es una biblioteca muy popular y rica en funciones. Entonces comencemos. Aquí en la terminal, NPM instala Winston Hermoso. Ahora, volvamos a la página del NPM. Aquí puedes ver que la forma recomendada de usar Winston es crear tu propio registrador Y a continuación, tenemos un código de muestra para comenzar. Así que simplemente copiaré este código y lo modificaré de acuerdo a nuestra app. Copia todo esto y pégalo aquí en arrodt Js. En la parte superior, tenemos nuestro módulo Winston. Entonces tenemos nuestro registrador, que se crea usando este método create logger. Contiene un objeto con pocas propiedades, nivel, formato, meta por defecto y transportes Entonces déjame explicarte cómo funciona esto. Primero, tenemos nivel de registro. Así que el nivel controla qué registros se van a procesar. Eso significa que filtra los registros por gravedad. Por lo que se supone que la severidad de todos los niveles es numéricamente ascendente de lo más importante a lo menos importante Eso significa que si tenemos error, entonces tiene una severidad de cero y tenemos la prioridad más alta. De igual manera, tenemos uno, info, STDP y verbos depurar y tontos con una severidad de seis, y tiene la menor prioridad Entonces aquí hemos establecido el nivel predeterminado en info, es decir, todos los mensajes de info, advierten y error quedarán rezagados Y si establecemos el nivel a verbos, entonces todos los mensajes de verbos y por encima de los niveles quedarán bloqueados A continuación, tenemos formato. Por lo que se utiliza un formato para personalizar cómo aparecen los registros. Eso es un texto plano, un objeto JCN o con marca de tiempo Y hay más formatos, estos se implementan en forma de registro, un módulo separado de Winston, y puedes echar un vistazo a este módulo para ver todos los formatos disponibles Aquí vamos a usar el JCNFMat y no necesitamos esta Ahora, este objeto logger tiene una matriz de transportes. Entonces, un transporte es esencialmente un dispositivo de almacenamiento para nuestros registros. Por lo que define dónde se envían los registros. Winston viene con algunos transportes centrales. Son Consola para registrar mensajes en la pila de consola y HTTP para llamar a un punto final SDDB para registrar mensajes También hay plugins para Winston. Hay otros módulos NPM para registrar mensajes en Mongo DB y COS DB, que es otra base de datos popular sin SQL También hay un complemento para registrar mensajes en Redis y Loge, que es un servicio muy popular de análisis y monitoreo de registros para aplicaciones empresariales Ahora aquí vamos a utilizar dos transportes diferentes, uno para registrar mensajes en un archivo y otro para iniciar sesión en la consola Entonces déjame cambiar esta a consola. Y no necesitamos esta propiedad de nombre de archivo aquí. Nuestro registrador está listo para usar, y si solo quieres tener un archivo de registros en formato JSON, este código es suficiente para hacerlo. No obstante, hay más en Winston. También es posible establecer un formato personalizado y un nivel personalizado en cada transporte por separado. Y cualquier número de formatos se pueden combinar en un solo formato usando el formato dot combine. Entonces voy a usar algunos formatos en nuestros transportes y luego combinarlos para una mejor experiencia Déjame mostrarte cómo hacer esto. En primer lugar, eliminemos este nivel y formato predeterminados. Ahora en la consola, quiero usar colores para registrar niveles basados en el mapeo personalizado. Para eso, podemos usar el formato de colorar y combinarlo con formato simple Entonces aquí, agregamos un formato de propiedad, y luego llamamos al método combinado, el winston dot format dot combine y simplemente pasamos los formatos que queremos combinar Así winston dot format dot colorIE y winston dot format dot También queremos darle un nivel de info. Entonces como mencioné antes, todos los mensajes de info uno y niveles de error se registrarán en la consola. Eso es. De igual manera, podemos personalizar nuestro transporte de archivos. Como puede ver, el nivel personalizado ya está configurado en error. Genial. Aquí, queremos que los registros sean más legibles agregando fecha y hora actuales. Se puede hacer combinando formatos timestamp y JCN. Entonces aquí, una vez más, estoy llamando a combinar. Y luego pasar wstin dot forma dot Time STAMP e instin dot fam dot JCN Al hacerlo, hemos agregado una marca de tiempo a cada error que pueda ocurrir dentro del objeto JSN Finalmente, necesitamos usar este registrador en nuestro middleware de error Entonces llamamos logger dot log. Luego pasamos un objeto con un nivel de propiedad, que podemos establecer como error o simplemente puedes usar el método de ayuda de error para registrar el error directamente. Así. Ahora, sólo tenemos que pasar el mensaje de error. Entonces establecemos la propiedad message para errar mensaje de punto. Ahora para demostrarlo, vayamos a los autos punto js. Aquí en la ruta get cars, voy a lanzar un error. Así que lanza nuevo error no es capaz de buscar autos. Entonces imaginemos en algún lugar de la aplicación, se arroja un error con la implementación actual. Nuestro middleware de error atrapará esa excepción. Lo registrará usando Winston y devolverá el error 500 al gravamen Entonces vamos a probar esto. Voy a ejecutar la aplicación, Norman Beautiful. Ahora, de vuelta en cartero, enviemos una solicitud get al punto final de autos Bien. Así que aquí está nuestro error interno del servidor. Ahora bien, si nos fijamos en la consola, tenemos error porque usamos el método de error de punto Winston, y su color es rojo Y este es el mensaje de error que hemos arrojado, no capaces de ir a buscar autos Entonces este es el transporte de consola que hemos personalizado en el registrador. Ahora en nuestro proyecto, puedes ver aquí tenemos este nuevo archivo, error dot log. Aquí tenemos un objeto JSON con un nivel de pocas propiedades, que es mensaje de error no es capaz de recuperar autos y la marca Entonces, en el futuro, podrá consultar el archivo de registro y tal vez extraer solo los errores en una fecha específica. Entonces este es un panorama general. Simplemente llamamos logger dot error o uno de los métodos helper. Y dependiendo del transporte que tengamos configurado, Winston registrará el mensaje dado En la próxima conferencia, te voy a mostrar cómo iniciar sesión en Mongo DB 8. Registro en MongoDB: Todo bien. Ahora déjame mostrarte cómo registrar mensajes en Manga Deb El registro a Mangaib se hace bastante simple con otro paquete de NPM, bastante simple con otro paquete de NPM, Winston Mangaib. Así que vamos a instalarlo. NPM instalar Winston Mangaib. La versión 6.0 0.0. Así que asegúrate de tener exactamente la misma versión. De lo contrario, lo que te voy a mostrar no va a funcionar en tu sistema. De vuelta en E Js En la última conferencia, agregamos archivos personalizados y transportes de consola Ahora vamos a agregar un nuevo transporte Manga Divi. Primero, tenemos que ir a la cima. Después de cargar Winston, necesitamos cargar Winston Manga DB requieren Winston Manga requieren Winston Y aquí no nos importa lo que se exporta de este módulo. Sólo tenemos que requerirlo. Bien con esto, podemos venir aquí y llamar a logger punto en el nuevo Winston Dot transporta Manga B. Pasamos en opciones objeto hay algunas propiedades Aquí hay algunas propiedades que puedes consultar en la documentación. El que necesitas establecer es DB. Así que configuramos esto a la cadena de conexión de nuestra base de datos, Manga DB holland 127.0 0.0 0.142 7017 Ahora en un escenario del mundo real, es posible que desee separar su registro de su base de datos operativa. Esa es una decisión que varía de un entorno a otro. Aquí, vamos a utilizar la misma base de datos para registrar nuestros errores. Bien, ya terminamos con esto. Ahora, no necesitamos hacer ningún otro cambio. Entonces, la próxima vez que haya un error en la aplicación porque tenemos otro transporte, Winston almacenará automáticamente nuestro error en Mongadib Así que volvamos a ejecutar la aplicación. Y de vuelta en Cartero, enviar una solicitud al punto final de autos Ahora, echemos un vistazo a MongAV Compass. Así que aquí está nuestra base de datos Fairwheel. Vamos a refrescarnos. Podemos ver que tenemos un nuevo registro de colección, y este es el mensaje que nos faltaba Entonces aquí está la marca de tiempo. El nivel se establece en error. Y aquí está el mensaje, no es capaz de ir a buscar autos. Ahora en la última conferencia, hablé de establecer un nivel personalizado en cada transporte por separado. Entonces aquí, tal vez solo quieras bloquear los errores en Mongoib No desea almacenar mensajes de información o mensajes de depuración. Si ese es el caso, aquí en el objeto options, también establece la propiedad level en error. Entonces con esto, solo se registrarán los mensajes de error. Ahora bien, como discutimos antes, si le dijiste esto a info, porque el nivel de información tiene una prioridad de dos y es el tercero en el nivel de registro, solo se registrará la advertencia de error, y los mensajes de información. Nada más allá de la información se registrará en Manga Divi. 9. Excepciones no atrapadas: Ahora bien, este middleware de error que hemos agregado aquí solo capta errores que ocurren como parte de la canalización de procesamiento de solicitudes Entonces esto es particular para Express. Si se lanza un error fuera del contexto de Express, este middleware no será auto Déjame mostrarte. En la parte inferior de este archivo, después de la exportación, voy a lanzar un nuevo error. Así que lanza nuevo error, algo falló durante el arranque. Por lo que este error se arroja fuera del contexto de procesar una solicitud. Está fuera del contexto de Express. Entonces ahora, cuando ejecute esta aplicación, verá que este error se bloquea el proceso, y Winston no podrá almacenarlo en el registro Para verificar esto, déjame ir a nuestro archivo de registro, eliminar todo aquí, guardar ahora de nuevo en la terminal. Ejecutemos nuestra aplicación. Norman, Bien, para que veas que nuestra app se estrelló, y aquí está nuestro error Algo falló durante la puesta en marcha. Y si miras el archivo de registro, puedes ver que aquí no hay nada. Entonces, si implementas esta aplicación en producción, tu aplicación no funcionará, y no hay forma de que sepas qué salió mal a menos que tengas acceso a la consola en el servidor. Ahí es donde entra Winston. Le permite capturar y registrar excepciones sin cortar sin esfuerzo Entonces en esta conferencia, voy a mostrarles cómo manejar adecuadamente las excepciones no capturadas en un proceso de nudo Esto es a un nivel superior. No está atado a expresar. Ahora, de vuelta en EOD o Js, aquí, al crear su registrador, agregue la propiedad de un manejador de excepciones y pasarle una matriz con una instancia de transporte Entonces manejadores de excepciones. Lo configuramos en una matriz donde pasamos una instancia de transporte, nuevo Winston dot transporta archivo Toma un objeto con un nombre de archivo de propiedad. Y aquí queremos registrar las excepciones sin cortar en un archivo separado Así que permítanme llamar a esto excepciones dot log. Y eso es todo. Fácil, ¿verdad? Ahora bien, ¿y si ya ha configurado un registrador y desea habilitar el manejo de excepciones más adelante? Eso no es problema. Puede utilizar excepciones método de manejador de punto. Déjame mostrarte. Entonces voy a elogiar esto y a continuación, después de definir nuestro logger, llamamos logger dot exceptions punto handle y pasamos la instancia de transporte como hicimos antes Así que nuevo transporta archivo punto. Nombre de archivo excepciones dot lag. Ahora bien, este enfoque es excelente para la flexibilidad a medida que su aplicación evoluciona Por último, no queremos que nuestra aplicación estrelle después de registrar la excepción sin cortar Por defecto, Winston sale del proceso después de registrar la excepción no capturada Puede deshabilitar este comportamiento configurando exit on error property en falls al crear su registrador. Entonces aquí, después de los manejadores de excepciones, configuramos exit on error a falls, o puedes asignarlo dinámicamente así El punto del registrador en el error es falso. Y permítanme comentar éste. Ahora, de vuelta a la terminal, corramos esto una vez más. Tenga en cuenta que esta vez el proceso no terminó porque aquí cogimos la excepción. Entonces el proceso termina si no captas una excepción ¿Bien? Ahora, echemos un vistazo a nuestro archivo de registro de excepciones. Puedes ver nuestro mensaje de error, algo falló durante el arranque. Con Winston, puede administrar fácilmente excepciones sin cortes y controlar el comportamiento de nuestras aplicaciones durante errores inesperados En la próxima conferencia, vamos a ver los rechazos de promesas inmanejables 10. Rechazos no manejados: En la última conferencia, hablamos sobre el manejo de excepciones no capturadas Entonces, si hay una excepción en tu aplicación y no has captado esa excepción usando un bloque de caché, puedes usar esta propiedad de manejadores de excepciones del registrador para registrarlo en un archivo usando Winston Al igual que con las excepciones no capturadas, Winston facilita almacenar en caché y registrar rechazos no manejados Con la configuración actual, un rechazo no controlado también se registrará en nuestro archivo de registro de puntos de excepciones sin bloquear la aplicación Déjame mostrártelo. Entonces aquí en error punto Js, estamos lanzando una excepción. Sustituyamos esto por una promesa rechazada. Tan constante promesa. Configuramos esto para prometer punto, rechazar y pasar un objeto de error con un mensaje, promesa rechazada. Así que imagina que este proceso representa el resultado de una operación asíncrona como una llamada a una base de datos o un servicio TDP remoto, y así Entonces tenemos una promesa rechazada. Y como te dije antes, con promesas, o llamamos entonces, y luego deberíamos llamar a catch para asegurarnos de manejar rechazos, o si estamos usando la sintaxis Ainc y esperar, esperamos la promesa, pero debemos poner esto en un try cachblock para caso de las excepciones En este código, tenemos una promesa, y voy a llamar luego pasar una simple consola de devolución de llamada punto log D. Pero no voy a llamar a caché Entonces tendremos un rechazo incontrolado. Ahora bien, si ejecutas la app Nomon nuestra app está funcionando bien. Y si revisas el archivo de registro de excepciones, aquí está nuestra promesa de rechazo no manejada rechazada Entonces Winston automáticamente captó esto como excepción no capturada y lo registró en excepciones dot log IL sin embargo, con Winston, tiene manejadores de rechazo de propiedad para manejar los rechazos no manejados Déjame mostrarte cómo hacerlo. Aquí puede habilitar el manejo de rechazo al crear su registrador. Así que al igual que agregamos manejadores de excepciones, podemos agregar manejadores de rechazo y pasarle una variedad de incienso de transporte Así que los manejadores de rechazo, lo configuran en una matriz. Después pasamos nuevos Winston dot transporta dot pile. Toma un objeto con nombre de archivo. Ahora quiero registrar los rechazos por separado. Entonces voy a llamarlo rechazos dot log, y eso es todo. Esta configuración escribe todos sus rechazos no manejados rechazos dedicados archivo de registro de puntos Ahora bien, ¿y si ya has configurado tu registrador y quieres manejar los rechazos de promesas más tarde Al igual que el manejo de excepciones, Winston proporciona el método de manejo de rechazos. Entonces déjame comentar esto a continuación. Justo después de llamar a las excepciones de punto de logger, llamamos logger punto rechazos punto handle y simplemente pasamos una instancia de transporte nuevo Winston punto ransport archivo reacciones dot Este enfoque le permite agregar un transporte específicamente para rechazos incluso después de que se inicialice su registrador Así que vamos a probarlo de nuevo en el punto de índice del nodo terminal JS. Todo bien. Mira esta advertencia, rechazo incontrolado. Y aquí está nuestro error. Ahora bien, si nos fijamos en el registro, tenemos un nuevo archivo rechazos dot log Mira, aquí está nuestro rechazo de promesa incontrolado, y esta vez, no está registrado en el archivo de registro de puntos de excepciones Ahora con la versión actual del nodo, este rechazo de promesa incontrolado debería terminar el proceso de asentimiento Pero como puedes ver, este proceso sigue en marcha. Estamos conectados a Mongo DB. Esto sucedió debido a la propiedad exit on error en nuestro logger, que configuramos para caídas. Entonces, ya sea que esté lidiando con una excepción no capturada o una reacción no controlada, como mejor práctica, debe terminar el proceso de nodo Entonces deberías salir de aquí porque en este punto, tu proceso puede estar en un estado impuro Entonces, como mejor práctica, debemos terminar el proceso y reiniciarlo para asegurarnos de comenzar con un estado limpio. Ahora bien, podría preguntarse, si terminamos el proceso, ¿cómo vamos a reiniciarlo en producción? Bueno, hay herramientas para eso, que llamamos gestores de procesos. Y en el futuro, vamos a mirar uno de esos. Entonces voy a modificar este código, y simplemente eliminamos la propiedad exit on error porque por defecto, Winston saldrá después de registrar una excepción no capturada o un rechazo incontrolado Una pregunta que podrías tener es si debes registrar los mensajes en un archivo o en una base de datos como Manga Div. Hay diferentes opiniones al respecto, pero personalmente creo que deberías usar ambos transportes porque cada transporte tiene fortalezas y debilidades Manga Di B u otras bases de datos son buenas para quering datos. Entonces, si quieres crear una aplicación cliente para consultar tu registro, es mucho más fácil consultar los datos en Mongo DB en lugar de un archivo plano como No obstante, es posible que tu servidor Mongo DB se caiga o no puedas conectarte a él por cualquier motivo En ese caso, es mejor usar el sistema de archivos porque el sistema de archivos siempre está disponible. En un ambiente de producción, rechazos de promesas inmanejables pueden pasar desapercibidos sin Entonces de esta manera, creamos una pista de auditoría de lo que salió mal y por qué. Y así es como manejas los rechazos inmanejables con Winston Ya sean excepciones sin cortes o rechazos de promesas, Winston le ayuda a mantener la visibilidad y confiabilidad en 11. Extraer rutas: Bien, así que aquí está el código en index o Js. El tema principal que tenemos aquí es la falta de separación de preocupaciones. Aquí están sucediendo tantas cosas, y por eso tenemos una gran cantidad de declaraciones requeridas en la parte superior de este módulo. Debajo de eso, puedes ver que tenemos algún código de configuración. Después de eso, tenemos algo completamente diferente, que se trata de conectarnos a la base de datos Mongo Di Ba Luego pasamos a configurar nuestras rutas en varios middleware Estas son preocupaciones diferentes. No deben mezclarse en un archivo o en un solo módulo. En este módulo, sólo debemos orquestar estas preocupaciones Por lo que los detalles de ellos deben trasladarse a diferentes módulos. Por ejemplo, los detalles de configuración de rutas o los detalles de conexión a base de datos Mongo DB, deben estar separados Entonces en esta conferencia, nos vamos a centrar en extraer rutas en un módulo separado. Así que vamos a crear una nueva carpeta llamada initialize. Aquí, voy a agregar un nuevo archivo rutas punto JS, y aquí deberíamos exportar una función. Así módulo dot Exportaciones. Ponemos esto a una función. Ahora, en esta función, voy a agregar todo el código para configurar nuestras rutas y otro middleware Así que de vuelta en index o Js, voy a cortar todo el código y moverlo aquí. Así que mira las dependencias aquí. Tenemos una dependencia al objeto app para expresar, todos estos routers, como empresas , clientes, etc. Así que de vuelta en index o Js en la parte superior en la línea 14, así es como creamos el objeto app. Deberíamos tener una sola instancia de eso en toda la aplicación. En otras palabras, no queremos cargar Express y luego llamarlo para crear un objeto app en nuestro nuevo módulo. Por lo que queremos enviar una referencia a esta app a este nuevo módulo. Entonces esta función debería tomar app como argumento. ¿Bien? Ahora, de vuelta en index o Js, aquí tenemos el objeto app. Podemos cargar nuestro nuevo módulo que es rutas inicializadas. Esto devuelve una función, por lo que la llamamos y pasamos el objeto app. Eso es. Es todo lo que tenemos que hacer. Ahora vamos a limpiar este módulo. Entonces todos estos enrutadores que aquí hemos importado, como empresas, clientes, etc., todos estos deben trasladarse a nuestro nuevo módulo porque no los hemos referenciado en ningún otro lugar del módulo de índice. Así que recorta aquí, pégalos en la parte superior. Hemos agregado la mayoría de las dependencias. También necesitamos Express y el error middleware. Así podemos cargar el Express en la parte superior, const Express. Requerir Express. Ahora para el error middleware, voy a sacarlo de index o Js porque este es el único lugar en el que estás haciendo referencia a esta el único lugar en el que estás haciendo referencia Aquí está nuestro middleware de error. Reduzca en rutas o Js, y agreguemos eso aquí. Ahora, volviendo a index o Js, se puede ver que el core en este módulo ya es mucho más corto. Ya no tenemos tantas declaraciones requeridas, y además la implementación es un poco más limpia. Ahora una última cosa volver al módulo de rutas, necesitamos cambiar las rutas a estos enrutadores porque la carpeta rutas no está dentro de la carpeta inicializada Entonces en cualquier lugar que tengamos peri slash, voy a reemplazar eso con periodo periodo Entonces aquí he seleccionado estos dos personajes. En el código VS, podemos habilitar la edición de múltiples cursor. Estoy manteniendo pulsado Control y D en Windows. Si estás usando Mac, el atajo probablemente sea Comando D. Así que mira, estoy seleccionando varias instancias y luego podemos reemplazarlas todas de una vez. Así periodo periodo. Hecho. 12. Extraer la lógica de registro: Aquí está nuestro error Js middleware. En esta conferencia, vamos a mover todo el código para configurar registro con diferentes módulos. Eso es todo lo que esté relacionado con Winston y manejo promesas rechazadas y excepciones no capturadas Entonces, en la carpeta inicializada, agreguemos un nuevo archivo, loguemos dot js, y luego volvamos al error dot js Toma todo este código para configurar Winston. Consígalo y muévelo a los puntos de registro aquí mismo. Ahora, debemos exportar este logger, así módulo dot Exportaciones. Y queremos llamarlo Logger. Entonces logger, configuramos esto en Logger. Ahora volvemos al índice punto js. También me gustaría mover esta sentencia require para manejar errores asíncronos en Express Prefiero poner esto en nuestro módulo de registro, que se trata de manejar y errores de registro. Así que vamos a cortarlo de aquí y pegarlo en el módulo logging dot js. Ahora, finalmente, tenemos que volver al index dot js y cargar el módulo de registro. Requerir inicializa Logging. Tenga en cuenta que pongo esto primero. Así que por si acaso obtenemos un error en la carga de otros módulos, para asegurarnos de bloquear ese error y terminar el proceso. Entonces terminamos con esta refactorización como ejercicio. Quiero que muevas todo el código para tratar con la inicialización de la base de datos a un módulo separado llamado dbdt Js Tendrás mi solución en la próxima conferencia. 13. Extraer la lógica de la base de datos: Aquí en el punto índice JS, este es el único código que tenemos para la inicialización de la base de datos Entonces aquí en la carpeta inicializada, agreguemos un nuevo archivo, dw dot JS Y aquí vamos a exportar una función. Así módulo dot Exportaciones. Ponemos esto a una función. Y luego mover todo el código de inicialización de la base de datos aquí mismo Ahora, voy a hacer algunos cambios aquí. En primer lugar, cuando nos conectamos, no quiero hacer Consultar en registro. Prefiero registrar esto como un mensaje informativo usando Winston Entonces, en la parte superior, carguemos nuestro registrador para requerir Logging. Y necesitamos desestructurar logger, así que Canst Cebrass Entonces, ¿por qué lo estamos reestructurando? Si recuerdas, en el logging dot js, hemos asignado el objeto logger como una propiedad de module dot export. Entonces, para acceder a la propiedad del registrador, es necesario desestructurarla. Lo hice a propósito para un rápido repaso. Ahora volvemos a db dot js. Como tenemos nuestro registrador ahora, podemos reemplazar esta consola que registra con logger dot info. También debemos eliminar este método de caché porque si no podemos conectarnos a Mongo Di B, queremos registrar esa excepción y terminar el proceso Con la implementación actual, estamos manejando esta promesa rechazada aquí mismo, y todo lo que estamos haciendo es mostrar este mensaje en la consola. Entonces no vamos a registrar esto. No estamos terminando el proceso. Yo uso esto aquí específicamente con fines de demostración, pero con la nueva implementación, no necesitamos esto. Entonces eliminemos esto y finalmente, necesitamos importar mangosta en la parte superior Voy a sacar esto del módulo indexado o Js. Así que de vuelta en indexado o Js en la parte superior, voy a quitar esta línea para importar mangosta y luego ponerla aquí mismo Así que aquí está nuestro módulo de base de datos. Se puede ver que el código está muy limpio, muy corto. Tenemos una sola responsabilidad. No tenemos demasiadas cosas mezcladas. Por último, necesitamos cargar este módulo en index o Js. Entonces aquí, voy a llamar requerir inicializar DV. Aquí obtenemos una función, entonces la llamamos. Ahora verifiquemos eso con nuestra implementación actual. Si no podemos conectarnos a la base de datos durante la inicialización de la aplicación, se registra esa excepción y se terminará el proceso Así que abre una nueva terminal. Voy a detener el proceso Mongo DB con nombre de servicio de parada Mongo DV Y luego de vuelta a nuestra ventana terminal, nodo, indexado o Js Así que aquí está nuestro rechazo inmanejado Se termina el proceso. Y si nos fijamos en rechazos dot log, podemos ver que el rechazo se registra aquí. Hermoso. Entonces por eso te dije deberíamos eliminar el método de caché aquí y dejar que nuestro manejador de errores global ocupe de esa promesa rechazada Aquí está tu próximo ejercicio. Quiero que vuelvas a index o Js y extraigas todo el código para lidiar con la configuración a un módulo separado. Entonces más específicamente, estoy hablando de estas pocas líneas aquí donde buscamos los ajustes de configuración esenciales durante la inicialización de la aplicación Verás mi solución a continuación. 14. Extraer la lógica de configuración: Todo bien. Empecemos agregando un nuevo archivo en la carpeta inicializada Entonces config dot js. Nuevamente, exportamos una función. Ahora, de vuelta en index o Js, tomamos todo el código para registrar los ajustes de configuración en este nuevo módulo. Así que aquí tenemos una dependencia a este módulo de configuración. Entonces voy a obtener esto de index dot js y cargarlo en la parte superior de este módulo. Bien, así que si no tenemos esta configuración, no queremos iniciar sesión en la consola. Más bien, queremos almacenar esto como un error fatal en nuestro registro. Entonces, en lugar de hacer un error de punto de consola y una salida de punto de proceso, es mejor lanzar una excepción, y entonces nuestra infraestructura actual atrapará esa excepción, registrará y terminará el proceso. Entonces lanzamos un nuevo error y usamos el mensaje de error. Además, como mejor práctica, siempre arroja objetos de error en lugar de cadenas, aunque puedas hacerlo en JavaScript. Porque cuando arrojas un objeto de error, este seguimiento de pila estará disponible para que lo veas más adelante. Si lanza una cadena con el mensaje de error, no tendrá el seguimiento de pila. Bien, entonces esa es otra mejor práctica para que la conozcas. Ahora por fin, volvamos a index o Js y carguemos este nuevo módulo. Por lo tanto requieren inicializar, flash config. Es una función, entonces la llamamos. Ahora, vamos a probarlo. Antes de eso, necesito iniciar el servicio Manga DV. Así que de vuelta en la terminal, vamos a ejecutar el nombre del servicio de inicio Manga DV. Bien, ahora tenemos que empezar de nuevo. Así que cierra todas las terminales y abre una nueva terminal así y ejecuta nod index dot JS Bien, así se termina el proceso, pero no se registra nada en la consola. Aunque si miras este archivo, puedes ver por qué se estrelló nuestra aplicación Error de Patel, la clave secreta JWD no está definida. Esto es bueno para un ambiente de producción. Pero si le das esta aplicación a un nuevo desarrollador y ellos la ejecutan, no tienen idea de lo que está pasando. Entonces, en nuestra implementación actual, estamos usando solo un transporte de archivos para excepciones no capturadas Por lo que también debemos agregar un transporte de consola para mostrar excepciones no capturadas en la consola Así que la nueva consola Winston dot transporta . Y eso es todo. Volvamos a la terminal y ejecutemos la aplicación una vez más. Puedes ver la razón por la que falló nuestra aplicación es porque no hemos definido la clave privada JWT Ahora quiero mostrarte algo. Así que vuelve al índice punto js. Mira el archivo JS del punto índice. Aquí solo tenemos 13 líneas de código. ¿Recuerdas lo que teníamos antes? Creo que teníamos de 30 a 40 líneas de código con una separación muy pobre de preocupaciones. Con esta nueva refactorización, estamos haciendo una sola cosa, configurando la aplicación Los detalles del registro, los detalles de las rutas, los detalles de la base de datos y otros aspectos se delegan a otros módulos. Este es un principio único de responsabilidad en la práctica. Aunque todavía hay margen para la refactorización, podemos mover esta configuración de joy y este código aquí, que se encarga de manejar la configuración del servidor e iniciarla Por lo que se lo dejaré para usted como una asignación de esta sección.