Saltar al contenido

Error node.js manejo y solución

El manejo de errores es un dolor, y es f√°cil subsistir durante mucho tiempo el error node.js sin tratar los errores correctamente. Sin embargo, la creaci√≥n de aplicaciones robustas de Node.js requiere lidiar con los errores correctamente, y no es dif√≠cil aprender c√≥mo hacerlo. Si est√° realmente impaciente, vaya a la secci√≥n “Resumen” para ver un tl; dr.

Este documento responder√° varias preguntas que los programadores nuevos en Node.js a menudo hacen el error node.js:

  • En las funciones que escribo, ¬Ņ throwcu√°ndo debo emitir un error y cu√°ndo debo emitirlo con una devoluci√≥n de llamada, un emisor de eventos o algo m√°s?
  • ¬ŅQu√© deben asumir mis funciones sobre sus argumentos? ¬ŅDebo comprobar que son los tipos correctos? ¬ŅDebo verificar restricciones m√°s espec√≠ficas, como que un argumento no es nulo, no es negativo, se parece a una direcci√≥n IP o similar?
  • ¬ŅC√≥mo debo tratar con los argumentos que no coinciden con lo que espera la funci√≥n? ¬ŅDebo lanzar una excepci√≥n o emitir un error a la devoluci√≥n de llamada?
  • ¬ŅC√≥mo puedo distinguir entre diferentes tipos de errores mediante programaci√≥n (p. Ej., Un error de “Solicitud incorrecta” frente a un error de “Servicio no disponible”)?
  • ¬ŅC√≥mo puedo proporcionar suficientes detalles con mis errores para que las personas que llaman puedan saber qu√© hacer al respecto?
  • ¬ŅC√≥mo debo manejar los errores inesperados? ¬ŅDebo usar trycatch, dominios, o algo m√°s?

Este documento est√° dividido en varias partes que se construyen unas sobre otras:

  • Antecedentes : lo que se espera que sepas ya.
  • Errores operativos frente a errores de programaci√≥n (error node.js ): introducci√≥n a dos tipos de errores fundamentalmente diferentes
  • Patrones para escribir funciones : principios generales para escribir funciones que producen errores √ļtiles
  • Recomendaciones espec√≠ficas para escribir nuevas funciones : una lista de verificaci√≥n de pautas espec√≠ficas para escribir funciones robustas que producen errores √ļtiles
  • Un ejemplo : documentaci√≥n de ejemplo y pre√°mbulo para una connectfunci√≥n.
  • Resumen : un resumen de todo hasta este punto.
  • Ap√©ndice: Propiedades convencionales para los objetos de error : una lista de nombres de propiedades para usar para proporcionar informaci√≥n adicional de manera est√°ndar

Fondo error node.js

Este documento asume:

  • Usted est√° familiarizado con la idea de excepciones en JavaScript, Java, Python, C ++, o cualquier lenguaje similar, y que sabe lo que significa throwcatchellos.
  • Est√°s familiarizado con la programaci√≥n en Node.js. Se siente c√≥modo con las operaciones as√≠ncronas y con el callback(err, result)patr√≥n de completar una operaci√≥n as√≠ncrona.
  • Debes saber por qu√© este patr√≥n:
function myApiFunc(callback) {
  /*
   * This pattern does NOT work!
   */
  try {
    doSomeAsynchronousOperation((err) => {
      if (err) {
        throw (err);
      }
      /* continue as normal */
    });
  } catch (ex) {
    callback(ex);
  }
}

No funciona para manejar el error node.js

También debe estar familiarizado con las cuatro formas principales de entregar un error node.js

  • throwEl error (por lo que es una excepci√≥n ).
  • pasar el error a una devoluci√≥n de llamada , una funci√≥n proporcionada espec√≠ficamente para manejar errores y los resultados de operaciones as√≠ncronas
  • pasar el error a una funci√≥n de promesa de rechazo
  • emitir un "error"evento en un EventEmitter

Discutiremos cu√°ndo usar cada uno de estos patrones a continuaci√≥n. Este documento no asume que sabes algo acerca de los dominios.

Finalmente, debes saber que en JavaScript (y en error node.js especialmente), hay una diferencia entre un error y una excepci√≥n. Un error es cualquier instancia de la Errorclase. Los errores pueden ser construidos y luego pasados directamente a otra funci√≥n o lanzados. Cuando se throwproduce un error, se convierte en una excepci√≥n. Aqu√≠ hay un ejemplo de c√≥mo usar un error como excepci√≥n:

throw new Error('something bad happened');

pero tambi√©n puedes crear un Errorsin lanzarlo:

callback(new Error('something bad happened'));

y esto es mucho m√°s com√ļn en el error node.js porque la mayor√≠a de los errores son as√≠ncronos. Como veremos, es muy raro que se necesite catchun error de una funci√≥n s√≠ncrona. Esto es muy diferente a Java, C ++ y otros lenguajes que hacen un uso intensivo de las excepciones.

Errores operacionales vs. errores del programador

Es √ļtil dividir todos los errores en dos categor√≠as amplias:

  • Los errores operativos

    representan problemas de tiempo de ejecuci√≥n experimentados por programas escritos correctamente. Estos no son errores en el programa. De hecho, estos suelen ser problemas con otra cosa: el sistema en s√≠ (p. Ej., Sin memoria o demasiados archivos abiertos), la configuraci√≥n del sistema (p. Ej., Sin ruta a un host remoto), la red (p. Ej., Conexi√≥n de socket) ), o un servicio remoto (por ejemplo, un error 500, falla de conexi√≥n o similar). Ejemplos incluyen:

    • Error al conectar con el servidor
    • No se pudo resolver el nombre de host
    • entrada de usuario inv√°lida
    • pide tiempo fuera
    • servidor devolvi√≥ una respuesta 500
    • z√≥calo colgar
    • el sistema no tiene memoria
  • Los errores del programador

    son errores en el programa. Estas son cosas que siempre se pueden evitar cambiando el c√≥digo. Nunca se pueden manejar adecuadamente (ya que, por definici√≥n, el c√≥digo en cuesti√≥n est√° roto).

    • Intent√© leer propiedad de “indefinido”
    • llamada una funci√≥n as√≠ncrona sin devoluci√≥n de llamada
    • pas√≥ una “cadena” donde se esperaba un objeto
    • pas√≥ un objeto donde se esperaba una cadena de direcci√≥n IP

La gente usa el t√©rmino “errores” para hablar de errores operativos y de programaci√≥n, pero son realmente muy diferentes. Los errores operacionales son condiciones de error con las que deben lidiar todos los programas correctos, y mientras se tratan, no necesariamente indican un error o incluso un problema grave. “Archivo no encontrado” es un error operacional, pero no significa necesariamente que algo est√© mal. Podr√≠a significar que el programa tiene que crear primero el archivo que est√° buscando.

Por el contrario, los errores del programador son errores. Son casos en los que cometi√≥ un error, tal vez olvidando validar la entrada del usuario, escribiendo mal el nombre de una variable o algo as√≠. Por definici√≥n no hay manera de manejar eso. Si lo hubiera, ¬°habr√≠a usado el c√≥digo de manejo de errores en lugar del c√≥digo que caus√≥ el error!

Esta distinci√≥n es muy importante: los errores operacionales son parte del funcionamiento normal de un programa. Los errores de programaci√≥n son errores.

A veces, tiene errores operativos y de programaci√≥n como parte del mismo problema ra√≠z. Si un servidor HTTP intenta usar una variable no definida y se bloquea, se trata de un error del programador. Todos los clientes con solicitudes en vuelo en el momento del accidente ver√°n un ECONNRESETerror, que normalmente se informa en Node como un “bloqueo de socket”. Para el cliente, eso es un error operacional separado. Esto se debe a que un cliente correcto debe manejar un servidor que falla o una red que no funciona.

De manera similar, la falla en el manejo de un error operacional es en s√≠ un error node.js del programador. Por ejemplo, si un programa intenta conectarse a un servidor pero recibe un ECONNREFUSEDerror, y no ha registrado un controlador para el 'error'evento del socket , el programa se bloquear√° y eso es un error del programador. La falla de la conexi√≥n es un error operacional (ya que eso es algo que cualquier programa correcto puede experimentar cuando la red u otros componentes en el sistema han fallado), pero la falla en su manejo es un error del programador.

La distinci√≥n entre los errores operativos y los errores del programador es la base para descubrir c√≥mo entregar los errores y c√≥mo manejarlos. Aseg√ļrate de entender esto antes de seguir leyendo.

Manejo del error node.js operacional.

Al igual que el rendimiento y la seguridad, el manejo del error node.js no es algo que se pueda vincular a un programa que ya no tenga manejo de errores. Tampoco puede centralizar todo el manejo de errores en una parte del programa, de la misma manera que no puede centralizar el “rendimiento” en una parte del programa. Cualquier c√≥digo que hace todo lo que eventualmente podr√≠a fallar (abrir un archivo, se conecta a un servidor, que se bifurcan un proceso hijo, etc.) tiene que considerar qu√© sucede cuando esa operaci√≥n falla. Eso incluye saber c√≥mo puede fallar (el modo de falla ) y lo que tal falla indicar√≠a. M√°s sobre esto m√°s adelante, pero el punto clave aqu√≠ es que el manejo del error node.js se debe hacer de manera detallada porque el impacto y la respuesta dependen exactamente de lo que fall√≥ y por qu√©.

Puede terminar manejando el mismo error en varios niveles de la pila. Esto sucede cuando los niveles inferiores no pueden hacer nada √ļtil, excepto propagar el error node.js a su interlocutor, lo que propaga el error a su interlocutor, y as√≠ sucesivamente. A menudo, solo la persona que llama de nivel superior sabe cu√°l es la respuesta adecuada, ya sea para volver a intentar la operaci√≥n, informar un error al usuario o algo m√°s. Pero eso no significa que deba intentar informar todos los errores a una √ļnica devoluci√≥n de llamada de nivel superior, ya que la devoluci√≥n de llamada en s√≠ misma no puede saber en qu√© contexto ocurri√≥ el error, qu√© partes de una operaci√≥n se completaron con √©xito y cu√°les realmente fallaron. .

Vamos a hacer esto concreto. Para cualquier error dado, hay algunas cosas que puedes hacer:

  • Tratar con el fracaso directamente. 

    A veces, est√° claro lo que tienes que hacer para manejar un error. Si recibe un ENOENTerror al intentar abrir un archivo de registro, tal vez esta sea la primera vez que el programa se ejecuta en este sistema y solo necesita crear el archivo de registro primero. Un caso m√°s interesante podr√≠a ser cuando se mantiene una conexi√≥n persistente a un servidor (por ejemplo, una base de datos), y se produce un error de “bloqueo de socket”. Por lo general, esto significa que el lado remoto o la red se han desintegrado, y con frecuencia es transitorio, por lo que normalmente tratar√° esto mediante la reconexi√≥n. (Esto no es lo mismo que volver a intentarlo, a continuaci√≥n, ya que no hay necesariamente una operaci√≥n en marcha cuando se produce este error).

  • Propaga el fallo a tu cliente. 

    Si no sabe c√≥mo lidiar con el error node.js, lo m√°s simple es abortar cualquier operaci√≥n que est√© tratando de hacer, limpiar lo que haya comenzado y devolver un error a su cliente. ( C√≥mo emitir ese error es otra pregunta, y se explica m√°s adelante). Esto es apropiado cuando espera que lo que sea que haya causado el error no cambie pronto. Por ejemplo, si el usuario le dio un JSON no v√°lido, no ayudar√° a intentar analizarlo de nuevo.

  • Vuelva a intentar la operaci√≥n. 

    Para errores de la red y servicios remotos (por ejemplo, un servicio web), a veces es √ļtil reintentar una operaci√≥n que devuelve un error node.js. Por ejemplo, si un servicio remoto da un 503 (Error de servicio no disponible), es posible que desee volver a intentarlo en unos segundos. Si va a volver a intentarlo, debe documentar claramente que puede volver a intentarlo varias veces, cu√°ntas veces intentar√° antes de fallar y cu√°nto tiempo esperar√° entre los reintentos. Adem√°s, no asuma que siempre debe volver a intentar una operaci√≥n. Si tienes varias capas en la pila (por ejemplo, un cliente te llama, lo llama otro cliente y es manejado por un humano), por lo general es mejor fallar r√°pido y dejar que el cliente final se ocupe. con reintentos. Si cada capa de la pila piensa que necesita volver a intentarlo en caso de errores, el usuario puede esperar mucho m√°s tiempo de lo debido porque, debido a que cada capa no se dio cuenta de que la capa subyacente tambi√©n estaba reintentando.

  • Explotar el error node.js. 

    Para los errores que realmente no pueden ocurrir, o que representar√≠an efectivamente los errores del programador si alguna vez lo hicieron (por ejemplo, no se pudo conectar a un socket localhost que se supone que est√° escuchando en el mismo programa), est√° bien registrar un mensaje de error y bloquearse. De todos modos, otros errores, como quedarse sin memoria, no pueden manejarse en un lenguaje din√°mico como JavaScript, por lo que puede ser totalmente razonable fallar. (Dicho esto, puede obtener ENOMEMoperaciones discretas como child_process.exec, y aquellas que puedemanejar razonablemente, y debe considerar hacerlo.) Tambi√©n puede explotar si no hay nada que pueda hacer razonablemente sobre algo y un administrador necesita arreglarlo. Por ejemplo, si se queda sin descriptores de archivo o no tiene permiso para acceder a su archivo de configuraci√≥n, no hay nada que pueda hacer al respecto, y un usuario tendr√° que iniciar sesi√≥n y arreglar las cosas de todos modos.

  • Registre el error y no haga nada m√°s. 

    A veces, no hay nada que puedas hacer al respecto, no hay nada que reintentar o cancelar, y tampoco hay raz√≥n para bloquear el programa. Un ejemplo podr√≠a ser si est√° haciendo un seguimiento de un grupo de servicios remotos que usan DNS y uno de esos servicios se cae del DNS. No hay nada que pueda hacer al respecto, excepto registrar un mensaje y continuar con los servicios restantes. Pero al menos debes registrar algo en este caso. (Hay excepciones a todas las reglas. Si esto es algo que puede suceder miles de veces por segundo, y no hay nada que puedas hacer al respecto, probablemente no valga la pena registrarlo cada vez que sucede. Sin embargo, hazlo peri√≥dicamente).

manejando el error node.js del programador

No hay nada que puedas hacer para manejar un error node.js de un programador. Por definici√≥n, el c√≥digo que se supon√≠a deb√≠a hacer algo estaba roto (por ejemplo, ten√≠a un nombre de variable mal escrito), por lo que no se puede solucionar el problema con m√°s c√≥digo. Si pudiera, simplemente usar√≠a el c√≥digo de manejo de errores en lugar del c√≥digo roto.

Algunas personas abogan por intentar recuperarse de los errores del programador, es decir, permitir que la operaci√≥n actual falle, pero siguen manejando las solicitudes. Esto no es recomendable. Considere que un error de programador es un caso en el que no pens√≥ cuando escribi√≥ el c√≥digo original. ¬ŅC√≥mo puede estar seguro de que el problema no afectar√° a otras solicitudes? Si otras solicitudes comparten un estado com√ļn (un servidor, un socket, un grupo de conexiones de base de datos, etc.), es muy posible que las otras solicitudes hagan lo incorrecto.

Un ejemplo t√≠pico es un servidor REST (por ejemplo, usando Restify ) donde uno de los manejadores de solicitudes lanza un ReferenceError (por ejemplo, utiliza un nombre de variable mal escrito). Hay muchas formas en que esto puede conducir a errores graves que son extremadamente dif√≠ciles de rastrear. Para algunos ejemplos:

  1. Algunos estados compartidos por solicitudes pueden dejarse nullundefinedo de lo contrario no ser v√°lidos, de modo que cuando la pr√≥xima solicitud intente usarla, tambi√©n explote.
  2. Se puede perder una conexi√≥n de base de datos (u otra), lo que reduce la cantidad de solicitudes futuras que puede manejar en paralelo. Esto puede llegar a ser tan malo que solo le quedan unas pocas conexiones, y termina manejando solicitudes en serie en lugar de concurrentemente.
  3. Peor a√ļn, una conexi√≥n postgres puede quedar dentro de una transacci√≥n abierta. Esto hace que postgres se “cuelgue” en versiones antiguas de filas en la tabla porque pueden ser visibles para esa transacci√≥n. Esto puede permanecer abierto durante semanas, lo que da como resultado una tabla cuyo tama√Īo efectivo crece sin l√≠mite, lo que provoca que las consultas posteriores disminuyan su orden de magnitud, desde unos pocos milisegundos hasta un minuto. Si bien este problema obviamente es espec√≠fico de postgres, es un ejemplo de lo mal que puede estar el estado de un programa incluso despu√©s de un simple error de programador.
  4. Una conexi√≥n puede dejarse en un estado autenticado y usarse para una conexi√≥n posterior. Puede terminar ejecutando una solicitud para el usuario incorrecto.
  5. Un z√≥calo puede dejarse abierto. Normalmente, el nodo usa un tiempo de espera de 2 minutos en los sockets inactivos, pero esto puede ser anulado, lo que resulta en un descriptor de archivo filtrado. Si esto sucede lo suficiente, puede quedarse sin descriptores de archivos y fallar. Incluso si no anula este tiempo de espera, el cliente puede bloquearse durante dos minutos y luego ver un error inesperado de “colgar”. El retraso de dos minutos hace que el problema sea molesto de tratar y de depurar.
  6. Las referencias de memoria se pueden dejar alrededor. Esto produce una fuga, lo que provoca que se quede sin memoria, o (peor) que aumente el tiempo empleado en GC, lo que hace que el rendimiento se estanque de forma horrible. Esto es particularmente dif√≠cil de depurar, y ser√≠a especialmente dif√≠cil asociarlo con los errores del programador que provocaron la fuga.

La mejor manera de recuperarse del error node.js del programador es bloquearse inmediatamente.

Debe ejecutar sus programas utilizando un reinicio que reiniciar√° autom√°ticamente el programa en caso de un bloqueo. Con un reinicio en marcha, el bloqueo es la forma m√°s r√°pida de restaurar un servicio confiable ante un error node.js transitorio de programador.

La √ļnica desventaja de fallar en el error node.js de programaci√≥n es que los clientes conectados pueden verse interrumpidos temporalmente, pero recuerde:

  • Por definici√≥n, estos errores siempre son errores. No estamos hablando de fallas leg√≠timas del sistema o de la red, sino de errores reales en el programa. Deben ser raras en producci√≥n, y la m√°xima prioridad debe ser depurarlas y arreglarlas.
  • Para todos los casos descritos anteriormente (y muchos m√°s), las solicitudes en vuelo no necesariamente se completar√°n con √©xito de todos modos. Pueden completarse con √©xito, pueden fallar el servidor nuevamente, pueden completarse incorrectamente de maneras obvias o pueden completarse err√≥neamente de maneras muy sutiles que son muy dif√≠ciles de depurar.
  • En un sistema distribuido confiable, los clientes deben poder lidiar con las fallas del servidor reconectando y volviendo a intentar las solicitudes. Las fallas de la red y del sistema son una realidad, ya sea que el propio programa Node.js le cause un error node.js pueda o no bloquearse.
  • Si su programa de producci√≥n se bloquea tan a menudo que estas desconexiones son un problema, entonces el problema real es que el servidor tiene tantos errores, no que se bloquee en el caso de un error node.js.

Si la desconexi√≥n de los clientes es un problema frecuente debido a que un servidor falla con tanta frecuencia, debe concentrarse en el error node.js que causa que el servicio se caiga, y hacer que sean excepcionales, en lugar de intentar evitar fallos en los casos en que el c√≥digo es obviamente incorrecto. La mejor manera de depurar estos problemas es configurar el Nodo para volcar el n√ļcleo en una excepci√≥n no detectada . Tanto en GNU / Linux como en sistemas basados en illumos, puede usar estos archivos centrales para ver no solo el seguimiento de la pila donde se bloque√≥ el programa, sino tambi√©n los argumentos de cada una de estas funciones y la mayor√≠a de los otros objetos de JavaScript, incluso aquellos a los que solo se hace referencia cierres Incluso sin los volcados de n√ļcleo configurados, puede usar la informaci√≥n de la pila y los registros para comenzar con el problema.

Finalmente, recuerde que un error node.js de programador en un servidor simplemente se convierte en un error operacional en un cliente. Los clientes tienen que lidiar con los servidores que fallan y los errores de red. Eso no es solo te√≥rico, ambos realmente ocurren en los sistemas de producci√≥n.

Patrones para escribir funciones para el error node.js

Hemos hablado acerca de c√≥mo manejar los errores, pero cuando est√° escribiendo una nueva funci√≥n, ¬Ņc√≥mo entrega los errores al c√≥digo que llam√≥ a su funci√≥n?

Lo m√°s importante que debe hacer es documentar lo que hace su funci√≥n, incluidos los argumentos que toma (incluidos sus tipos y cualquier otra restricci√≥n), lo que devuelve, qu√© errores pueden ocurrir y qu√© significan esos errores. Si no sabe qu√© errores pueden ocurrir o no sabe qu√© significan, entonces su programa no puede ser correcto, excepto por accidente. Entonces, si est√° escribiendo una nueva funci√≥n, debe informar a las personas que llaman qu√© errores pueden ocurrir y qu√© significan.

¬ŅTiro, devoluci√≥n de llamada, rechazo o EventEmitter?

Hay tres patrones básicos para que una función entregue errores.

  • throwenv√≠a un error de forma s√≠ncrona, es decir, en el mismo contexto donde se llam√≥ a la funci√≥n. Si la persona que llama (o la persona que llama, …) us√≥ trycatch, entonces pueden detectar el error. Si ninguna de las personas que llamaron lo hizo, el programa generalmente falla. (El error tambi√©n puede ser manejado por dominios o por el evento “uncaughtException” en todo el proceso, que se analiza a continuaci√≥n).
  • Las devoluciones de llamada son la forma m√°s b√°sica de enviar un error de forma as√≠ncrona. El usuario le pasa una funci√≥n (la devoluci√≥n de llamada), y la invoca m√°s tarde cuando finaliza la operaci√≥n as√≠ncrona. El patr√≥n habitual es que la devoluci√≥n de llamada se invoca como callback(err, result), donde solo uno de errresultno es nulo, dependiendo de si la operaci√≥n se realiz√≥ correctamente o no.
  • Los rechazos de promesa son una forma com√ļn de enviar un error de forma as√≠ncrona. Este m√©todo est√° creciendo en popularidad desde el lanzamiento de Node.js versi√≥n 8 que incluye soporte para asyncawait. Esto permite escribir c√≥digo as√≠ncrono para que parezca un c√≥digo s√≠ncrono y detectar errores usando trycatch.
  • Para casos m√°s complicados, en lugar de usar una devoluci√≥n de llamada, la funci√≥n en s√≠ misma puede devolver un EventEmitterobjeto, y se espera que la persona que llama escuche los erroreventos en el emisor. Esto es √ļtil en dos casos particulares:
    • Cuando est√°s haciendo una operaci√≥n complicada que puede producir m√ļltiples errores o resultados m√ļltiples. Por ejemplo, piense en una solicitud que obtiene filas de una base de datos y luego las vuelve a transmitir a medida que llegan, en lugar de esperar a que todas lleguen primero. En este caso, en lugar de recibir una devoluci√≥n de llamada, su funci√≥n devolver√° un EventEmitter y emitir√° roweventos para cada resultado, un endevento cuando se hayan informado todos los resultados y un errorevento si se produce alg√ļn error.
    • Para los objetos que representan m√°quinas de estados complejas, donde pueden ocurrir muchas cosas as√≠ncronas diferentes. Por ejemplo, un socket es un emisor de eventos que puede emitir “connect”, “end”, “timeout”, “dren” y “close”. Es natural cometer “error” simplemente otro tipo de evento que el socket puede emitir. Al utilizar este enfoque, es importante tener claro cu√°ndo se emite “error”, si se pueden emitir otros eventos, qu√© otros eventos se pueden ver al mismo tiempo (por ejemplo, “cerrar”), en qu√© orden ocurren, y si el z√≥calo est√° cerrado al final.

En su mayor parte, agruparemos las devoluciones de llamada y los emisores de eventos en el mismo grupo de “entrega de error as√≠ncrono”. Si desea enviar un error de forma as√≠ncrona, generalmente desea utilizar uno u otro de estos (devoluci√≥n de llamada o emisor de eventos), pero no ambos.

Entonces, ¬Ņcu√°ndo se usa throwy cu√°ndo se usan las devoluciones de llamada o los emisores de eventos? Depende de dos cosas:

  • ¬ŅEs el error node.js un error operacional o un error del programador?
  • ¬ŅEs la funci√≥n en s√≠ misma s√≠ncrona o as√≠ncrona?

Con mucho, el caso m√°s com√ļn es el error node.js y este es un error  operacional en una funci√≥n as√≠ncrona. Para la mayor√≠a de estos, querr√° que su funci√≥n tome una devoluci√≥n de llamada como argumento, y simplemente pasar√° el error a la devoluci√≥n de llamada. Esto funciona muy bien, y es ampliamente utilizado. Consulte el fsm√≥dulo Nodo para ver ejemplos. Si tiene un caso m√°s complicado como los descritos anteriormente, es posible que desee utilizar un emisor de eventos en su lugar, pero a√ļn as√≠ entregar√° el error de forma as√≠ncrona.

El siguiente caso m√°s com√ļn es un error operacional en una funci√≥n s√≠ncrona JSON.parse. Para estas funciones, si encuentra un error operacional (como una entrada de usuario no v√°lida), debe entregar el error de forma s√≠ncrona. Puedes lanzarlo (mucho m√°s com√ļn) o devolverlo.

Para una funci√≥n dada, si cualquier error operacional puede entregarse de forma as√≠ncrona, entonces todos los errores operacionales deben entregarse de manera as√≠ncrona. Puede haber casos en los que sepa inmediatamente que la solicitud fallar√°, pero no debido a un error node.js del programador. Tal vez la funci√≥n almacena en cach√© los resultados de las solicitudes recientes y hay una entrada de cach√© con un error node.js que devolver√° a la persona que llama. Aunque sepa de inmediato que la solicitud fallar√°, debe entregar ese error de forma as√≠ncrona.

La regla general es que una funci√≥n puede entregar errores operacionales de forma sincr√≥nica (por ejemplo, mediante throwing) o de manera as√≠ncrona (pas√°ndolos a una devoluci√≥n de llamada o emitiendo erroren una EventEmitter), pero no deber√≠a hacer ambas cosas . De esta manera, un usuario puede manejar los errores ya sea manej√°ndolos en la devoluci√≥n de llamada o usando trycatch, pero nunca necesitan hacer ambas cosas. Cu√°l de ellos usan depende de c√≥mo la funci√≥n entrega sus errores, y eso debe especificarse con su documentaci√≥n.

Hemos dejado de lado los errores del programador. Recordemos que estos son siempre errores. Por lo general, tambi√©n se pueden identificar inmediatamente al verificar los tipos (y otras restricciones) en los argumentos al inicio de la funci√≥n. Un caso degenerado es cuando alguien llama a una funci√≥n as√≠ncrona pero no pasa una devoluci√≥n de llamada. Deber√≠a lanzar estos errores inmediatamente, ya que el programa est√° da√Īado y la mejor posibilidad de depuraci√≥n implica obtener al menos un seguimiento de pila y, idealmente, un archivo central en el punto del error. Para hacer esto, recomendamos validar los tipos de todos los argumentos al inicio de la funci√≥n.

Dado que los errores del programador nunca deben manejarse, esta recomendaci√≥n no cambia nuestra conclusi√≥n anterior de que una persona que llama puede usar trycatcho una devoluci√≥n de llamada (o emisor de eventos) para manejar los errores, pero nunca necesita usar ambos. Para m√°s informaci√≥n, vea “(No) manejar errores de programador” m√°s arriba.

Aquí hay un resumen de estas recomendaciones con algunas funciones de ejemplo en las bibliotecas principales de Node, en orden aproximado de la frecuencia con la que surge cada tipo de problema:

Ejemplo de funciónTipo de funcError de ejemploTipo de errorComo entregarUsadores de llamadas
fs.statasincrónicoarchivo no encontradoOperacionalllamar de vueltamanejar el error de devolución de llamada
JSON.parsesincrónicomala entrada del usuarioOperacionalthrowtry/catch
fs.statasincr√≥niconull para nombre de archivoprogramadorthrowninguno

Los errores operativos en una funci√≥n as√≠ncrona (fila 1) son, con mucho, el caso m√°s com√ļn. El uso de funciones s√≠ncronas que informan errores operativos (fila 2) es muy raro en Node.js, excepto en la validaci√≥n de entrada del usuario. Sin embargo, con el lanzamiento de la versi√≥n 8 de Node.js, las personas est√°n comenzando a prometer estas funciones as√≠ncronas y est√°n utilizando esperar dentro de un try / catch. Los errores del programador (fila 3) nunca deben suceder, excepto en el desarrollo.

¬ŅMala entrada: error node.js del programador o error operacional?

¬ŅC√≥mo sabes qu√© es un error node.js de programador frente a un error operacional? En pocas palabras: depende de usted definir y documentar qu√© tipos permitir√° su funci√≥n y c√≥mo intentar√° interpretarlos. Si obtienes algo distinto de lo que has documentado para aceptar, es un error node.js de programador. Si la entrada es algo que usted ha documentado que debe aceptar pero no puede procesar ahora, es un error operacional.

Debe usar su criterio para decidir qu√© tan estricto quiere ser, pero podemos hacer algunas sugerencias. Para concretar, imagine una funci√≥n llamada “conectar” que toma una direcci√≥n IP y una devoluci√≥n de llamada e invoca la devoluci√≥n de llamada de forma as√≠ncrona despu√©s de tener √©xito o fallar. Supongamos que el usuario pasa algo que obviamente no es una direcci√≥n IP v√°lida, como 'bob'. En este caso, tienes algunas opciones:

  • Documente que la funci√≥n solo acepta cadenas que representan direcciones IPv4 v√°lidas y arroje una excepci√≥n inmediatamente si el usuario la aprueba 'bob'. Esto es muy recomendable.
  • Documento que la funci√≥n acepta cualquier cadena. Si el usuario pasa 'bob', emita un error as√≠ncrono que indica que no pudo conectarse a la direcci√≥n IP 'bob'.

Ambos de estos son consistentes con las pautas sobre errores operacionales y errores del programador. Realmente est√° decidiendo si considerar tal entrada como un error de programador o un error operacional. En general, las funciones de validaci√≥n de entrada del usuario son muy flojas.Date.parse, por ejemplo, acepta una variedad de entradas, ese es b√°sicamente el punto. Pero para la mayor√≠a de las otras funciones, recomendamos enf√°ticamente que sea m√°s estricto en lugar de m√°s flexible. Cuanto m√°s intente su funci√≥n adivinar qu√© quiso decir la persona que llama (usando coerciones impl√≠citas, ya sea como parte de JavaScript o haci√©ndolo expl√≠citamente en su funci√≥n), es m√°s probable que adivine mal. En lugar de ahorrar a los desarrolladores el esfuerzo necesario para ser m√°s expl√≠citos, es posible que haga algo que desperdicie horas de tiempo para que el desarrollador realice la depuraci√≥n. Adem√°s, siempre puedes hacer que la funci√≥n sea menos estricta en futuras versiones si decides que es una buena idea, pero si descubres que tu intento de adivinar qu√© significaba la gente conduce a errores realmente desagradables, no puedes arreglarlo sin romper la compatibilidad.

Entonces, si un valor no puede ser v√°lido (por ejemplo, undefinedpara una cadena requerida o una cadena que se supone que es una direcci√≥n IP pero obviamente no lo es), debe documentar que no est√° permitido y arrojar un error inmediatamente si ve eso. Mientras lo documente, entonces estos son errores del programador, no errores operacionales. Al lanzar de inmediato, minimiza el da√Īo causado por el error y conserva la informaci√≥n que el desarrollador querr√≠a depurar el problema (por ejemplo, la pila de llamadas, y si est√° utilizando volcados de n√ļcleo, los argumentos y toda la memoria tambi√©n).

¬ŅQu√© pasa con los dominios y process.on('uncaughtException')?

Los errores operativos siempre se pueden manejar a trav√©s de un mecanismo expl√≠cito: detectar una excepci√≥n, procesar el error en una devoluci√≥n de llamada, manejar un evento de “error” en un EventEmitter, etc. Los dominios y el 'uncaughtException'evento de todo el proceso son principalmente √ļtiles para intentar controlar o recuperar errores de programador no anticipados. Por todas las razones descritas anteriormente, esto es muy desaconsejable.

Recomendaciones específicas para escribir nuevas funciones.

Hemos hablado de muchos principios rectores, así que ahora vamos a ser específicos.

1. Sea claro acerca de lo que hace su función.

Esto es lo m√°s importante que hay que hacer. La documentaci√≥n para cada funci√≥n de interfaz debe ser muy clara sobre:

  • que argumentos espera
  • Los tipos de cada uno de esos argumentos.
  • cualquier restricci√≥n adicional en esos argumentos (por ejemplo, debe ser una direcci√≥n IP v√°lida)

Si alguno de estos est√° mal o falta, es un error de programador y debe lanzarlo inmediatamente.

También querrás documentar:

  • Qu√© errores operacionales deben esperar las personas que llaman (incluyendo sus names)
  • c√≥mo manejar los errores operacionales (por ejemplo, se lanzar√°n, pasar√°n a la devoluci√≥n de llamada, se emitir√°n en un emisor de eventos, etc.)
  • el valor de retorno

2. Utilice Errorobjetos (o subclases) para todos los errores e implemente el Errorcontrato.

Todos sus errores deben usar la clase Error o una subclase de la misma. Debe proporcionar namemessagepropiedades, y stackdebe trabajar tambi√©n (y ser preciso).

3. Use la namepropiedad del error para distinguir los errores program√°ticamente.

Cuando necesite averiguar qu√© tipo de error es este, use la namepropiedad. Los nombres de JavaScript incorporados que puede reutilizar incluyen “RangeError” (un argumento est√° fuera de su rango v√°lido) y “TypeError” (un argumento tiene el tipo incorrecto). Para errores HTTP, es com√ļn usar el texto de estado dado por RFC para nombrar el error, como “BadRequestError” o “ServiceUnavailableError”.

No sientas la necesidad de crear nuevos nombres para todo. No necesita InvalidHostnameError, InvalidIpAddressError, InvalidDnsServerError, etc., cuando solo puede tener un solo InvalidArgumentError y aumentarlo con propiedades que digan lo que est√° mal (vea m√°s abajo).

4. Aumentar el Errorobjeto con propiedades que explican detalles.

Por ejemplo, si un argumento no era v√°lido, establezca propertyNameel nombre de la propiedad que no era v√°lida y propertyValueel valor que se pas√≥. Si no pudo conectarse a un servidor, use remoteIppara decir a qu√© IP intent√≥ conectarse. Si recibi√≥ un error del sistema, incluya la syscallpropiedad para indicar qu√© syscall fall√≥ y la errnopropiedad para decir qu√© sistema errno recibi√≥. Vea el ap√©ndice para ejemplos de nombres de propiedades para usar.

Por lo menos, usted quiere:

  • name: se usa para distinguir de manera program√°tica entre tipos amplios de errores (p. ej., argumento ilegal contra conexi√≥n fallida)
  • message: un mensaje de error legible por humanos. Esto deber√≠a ser lo suficientemente completo para que cualquiera que lo lea lo entienda. Si est√° pasando un error desde un nivel inferior de la pila, debe agregar algo al mensaje que explique lo que estaba haciendo. Vea el siguiente art√≠culo para m√°s informaci√≥n sobre envolver errores.
  • stack: en general, no te metas con esto. Ni siquiera aumentarlo. V8 solo lo calcula si alguien realmente lee la propiedad, lo que mejora dram√°ticamente el rendimiento para errores manejables. Si lees la propiedad solo para aumentarla, terminar√°s pagando el costo incluso si la persona que llama no necesita la pila.

Tambi√©n debe incluir suficiente informaci√≥n en el mensaje de error para que la persona que llama elabore su propio mensaje de error sin tener que analizar el suyo. Es posible que deseen localizar el mensaje de error, agregar un gran n√ļmero de errores o mostrar el mensaje de error de manera diferente (por ejemplo, en una tabla en un sitio web, o resaltando un campo de formulario de entrada de usuario incorrecto).

5. Si le pasa un error de nivel inferior a su interlocutor, considere envolverlo.

A menudo, encontrar√° que su funci√≥n as√≠ncrona funcAllama a otra funci√≥n as√≠ncrona funcBy que, si funcBemite un error, querr√° funcAemitir el mismo error. (Tenga en cuenta que la segunda parte no siempre sigue a la primera. A veces funcA, en cambio, lo volveremos a intentar. O a veces funcAignorar√° el error porque puede significar que no hay nada que hacer. Pero solo estamos considerando el caso simple en el que funcAquiere para devolver directamente funcBel error de aqu√≠.

En este caso, considere envolver el error en lugar de devolverlo directamente. Al envolver, nos referimos a la propagaci√≥n de un nuevo error que incluye toda la informaci√≥n del nivel inferior, m√°s un contexto √ļtil adicional basado en el nivel actual. El m√≥dulo verror proporciona una manera f√°cil de hacer esto.

Por ejemplo, suponga que tiene una funci√≥n llamada fetchConfig, que recupera la configuraci√≥n de un servidor desde una base de datos remota. Tal vez usted llama a esta funci√≥n cuando se inicia su servidor. Todo el camino en el inicio se ve as√≠:

  1. Cargar configuracion
    1. Con√©ctese al servidor de la base de datos. Esto a su vez:
      1. Resolver el nombre de host DNS del servidor de base de datos
      2. Haga una conexión TCP al servidor de base de datos.
      3. Autenticación en el servidor de la base de datos.
    2. Hacer la solicitud de DB
    3. Decodificar la respuesta.
    4. Cargar la configuracion
  2. Empezar a manejar solicitudes

Supongamos que en el tiempo de ejecuci√≥n hay un problema al conectarse al servidor de la base de datos. Si el paso de conexi√≥n en 1.1.2 falla porque no hay una ruta hacia el host, y cada nivel propaga el error a la persona que llama (como deber√≠a), pero no envuelve el error primero, entonces puede aparecer un mensaje de error como este :

myserver: Error: connect ECONNREFUSED

Esto obviamente no es muy √ļtil.

Por otro lado, si cada nivel envuelve el error devuelto desde el nivel inferior, puede obtener un mensaje mucho m√°s informativo:

myserver: failed to start up: failed to load configuration: failed to connect to
database server: failed to connect to 127.0.0.1 port 1234: connect ECONNREFUSED

Es posible que desee omitir el ajuste en algunos niveles y obtener un mensaje menos pedante:

myserver: failed to load configuration: connection refused from database at
127.0.0.1 port 1234.

Por otro lado, es mejor equivocarse al incluir más información en lugar de menos.

Si decide envolver un error, hay algunas cosas que debe considerar:

  • Deje el error original intacto y sin cambios, y aseg√ļrese de que el error subyacente todav√≠a est√© disponible para la persona que llama en caso de que desee obtener informaci√≥n de √©l directamente.
  • Use el mismo “nombre” para su error, o bien elija expl√≠citamente uno que tenga m√°s sentido. Por ejemplo, el nivel inferior podr√≠a ser un simple Error desde el nodo, pero el error del paso 1 podr√≠a ser un error de inicializaci√≥n. (Pero no se sienta obligado a crear nuevos nombres para errores si pueden distinguirse program√°ticamente mirando las otras propiedades).
  • Preserve todas las propiedades del error original. Aumente la messagepropiedad seg√ļn corresponda (pero no la cambie en el error original). Shallow-copia todas las otras propiedades como syscallerrnoy similares. Usted es el mejor de copiar todas las propiedades excepto por namemessagestack, en lugar de codificar una lista de propiedades para copiar de manera expl√≠cita. No hagas nada con eso stack, ya que incluso leerlo puede ser relativamente caro. Si la persona que llama quiere producir una pila combinada, debe iterar las causas e imprimir la pila de cada una.

En Joyent, usamos el m√≥dulo verror para envolver los errores, ya que es sint√°cticamente conciso. A partir de este escrito, todav√≠a no hace todo esto, pero se extender√° a hacerlo.

Un ejemplo del error node.js

Considere una funci√≥n que se conecta de forma as√≠ncrona a un puerto TCP en una direcci√≥n IPv4. Aqu√≠ hay un ejemplo de c√≥mo podemos documentarlo:

/*
 * Make a TCP connection to the given IPv4 address.  Arguments:
 *
 *    ip4addr        a string representing a valid IPv4 address
 *
 *    tcpPort        a positive integer representing a valid TCP port
 *
 *    timeout        a positive integer denoting the number of milliseconds
 *                   to wait for a response from the remote server before
 *                   considering the connection to have failed.
 *
 *    callback       invoked when the connection succeeds or fails.  Upon
 *                   success, callback is invoked as callback(null, socket),
 *                   where `socket` is a Node net.Socket object.  Upon failure,
 *                   callback is invoked as callback(err) instead.
 *
 * This function may fail for several reasons:
 *
 *    SystemError    For "connection refused" and "host unreachable" and other
 *                   errors returned by the connect(2) system call.  For these
 *                   errors, err.errno will be set to the actual errno symbolic
 *                   name.
 *
 *    TimeoutError   Emitted if "timeout" milliseconds elapse without
 *                   successfully completing the connection.
 *
 * All errors will have the conventional "remoteIp" and "remotePort" properties.
 * After any error, any socket that was created will be closed.
 */
function connect(ip4addr, tcpPort, timeout, callback) {
  assert.equal(typeof (ip4addr), 'string',
      "argument 'ip4addr' must be a string");
  assert.ok(net.isIPv4(ip4addr),
      "argument 'ip4addr' must be a valid IPv4 address");
  assert.equal(typeof (tcpPort), 'number',
      "argument 'tcpPort' must be a number");
  assert.ok(!isNaN(tcpPort) && tcpPort > 0 && tcpPort < 65536,
      "argument 'tcpPort' must be a positive integer between 1 and 65535");
  assert.equal(typeof (timeout), 'number',
      "argument 'timeout' must be a number");
  assert.ok(!isNaN(timeout) && timeout > 0,
      "argument 'timeout' must be a positive integer");
  assert.equal(typeof (callback), 'function');
  /* do work */
}

Este ejemplo es conceptualmente simple, pero demuestra algunas de las sugerencias de las que hablamos:

  • Los argumentos, sus tipos y otras restricciones en sus valores est√°n claramente documentados.
  • La funci√≥n es estricta en los argumentos que acepta y arroja errores (errores de programaci√≥n) cuando se obtiene una entrada no v√°lida.
  • Se documenta el conjunto de posibles errores operacionales. Los diferentes valores de “nombre” se utilizan para distinguir errores l√≥gicamente diferentes, y “errno” se utiliza para obtener informaci√≥n detallada sobre los errores del sistema.
  • La forma en que se entregan los errores se documenta ( callbackse invoca en caso de error).
  • Los errores devueltos tienen los campos “remoteIp” y “remotePort” para que un usuario pueda definir un mensaje de error personalizado (por ejemplo, cuando el n√ļmero de puerto est√° impl√≠cito, como lo ser√≠a con un cliente HTTP).
  • Aunque deber√≠a ser obvio, el estado despu√©s de una conexi√≥n fallida est√° claramente documentado: cualquier socket que se haya abierto ya se habr√° cerrado.

Esto puede parecer m√°s trabajo de lo que la gente suele poner por escrito en lo que deber√≠a ser una funci√≥n bien entendida, pero la mayor√≠a de las funciones no son tan universalmente entendidas. Todos los consejos deben ser ajustados y debe usar su criterio si algo es realmente simple, pero recuerde: diez minutos documentando las expectativas ahora pueden ahorrarle horas a usted u otra persona m√°s adelante.

Resumen del error node.js

  • Aprenda a distinguir entre errores operativos , que son anticipables, errores inevitables, incluso en programas correctos (por ejemplo, fallar en conectarse a un servidor), y errores de programador , que son errores en el programa.
  • Los errores operacionales pueden y deben ser manejados. Los errores del programador no pueden manejarse o recuperarse de manera confiable (ni deber√≠an serlo), y tratar de hacerlo hace que sean m√°s dif√≠ciles de depurar.
  • Una funci√≥n dada debe entregar errores operacionales ya sea de forma s√≠ncrona (con throw) o as√≠ncronamente (con una devoluci√≥n de llamada o emisor de eventos), pero no ambas. Un usuario deber√≠a poder usar trycatcho manejar los errores en la devoluci√≥n de llamada, pero nunca deber√≠a necesitar ambos. En general, usar throwy esperar que una persona que llama use trycatches bastante raro, ya que en Node.js no es com√ļn que las funciones s√≠ncronas tengan errores operativos. (La principal excepci√≥n son las funciones de validaci√≥n de entrada del usuario, como JSON.parse.)
  • Al escribir una nueva funci√≥n, documente claramente los argumentos que su funci√≥n espera, sus tipos, cualquier otra restricci√≥n (por ejemplo, “debe ser una direcci√≥n IP v√°lida”), los errores operacionales que pueden ocurrir leg√≠timamente (por ejemplo, falla para resolver un nombre de host, falla al conectarse a un servidor, cualquier error del lado del servidor, y c√≥mo esos errores se entregan al llamante (de forma s√≠ncrona, usando throwo as√≠ncronamente, usando una devoluci√≥n de llamada o un emisor de eventos).
  • Los argumentos que faltan o no son v√°lidos son errores del programador, y siempre debe hacerlo throwcuando eso sucede. Puede haber un √°rea gris alrededor de los par√°metros que el autor decide que son aceptables, pero si pasa una funci√≥n diferente de lo que est√° documentado para aceptar, eso siempre es un error del programador.
  • Al entregar errores, use la Errorclase est√°ndar y sus propiedades est√°ndar. Agregue toda la informaci√≥n adicional que pueda ser √ļtil en propiedades separadas. Cuando sea posible, utilice nombres de propiedades convencionales (ver m√°s abajo).

Apéndice: Propiedades convencionales para objetos de error node.js .

Se recomienda encarecidamente que utilice estos nombres para mantener la coherencia con los Errores entregados por el n√ļcleo de Node y los complementos de Node. La mayor√≠a de estos no se aplicar√°n a ning√ļn error dado, pero en caso de duda, debe incluir cualquier informaci√≥n que parezca √ļtil, tanto por programaci√≥n como por un mensaje de error personalizado.

Nombre de la propiedadUso previsto
localHostnameel nombre de host DNS local (por ejemplo, que est√° aceptando conexiones en)
localIpla dirección IP local (por ejemplo, que está aceptando conexiones en)
puerto localel puerto TCP local (por ejemplo, que est√° aceptando conexiones en)
nombre de usuario remotoel nombre de host DNS de alg√ļn otro servicio (por ejemplo, al que intent√≥ conectarse)
IP remotala direcci√≥n IP de alg√ļn otro servicio (p. ej., al que intent√≥ conectarse)
Puerto remotoel puerto de alg√ļn otro servicio (p. ej., al que intent√≥ conectarse)
caminoel nombre de un archivo, directorio o Unix Domain Socket (p. ej., que intentó abrir)
srcpathel nombre de una ruta utilizada como fuente (por ejemplo, para cambiar el nombre o copiar)
dstpathel nombre de una ruta utilizada como destino (por ejemplo, para cambiar el nombre o copiar)
nombre de hostun nombre de host DNS (por ejemplo, que intentó resolver)
ipuna dirección IP (p. ej., que intentó revertir-resolver)
nombre de la propiedadun nombre de propiedad de objeto o un nombre de argumento (por ejemplo, para un error de validación)
valor de propiedadun valor de propiedad de objeto (por ejemplo, para un error de validación)
syscallel nombre de una llamada al sistema que falló
errnoel valor simb√≥lico de errno(por ejemplo, "ENOENT").
No , no utilizar esto para los errores que en realidad no ajustan el valor de Cerrno.
Utilice “nombre” para distinguir entre los tipos de errores.

Notas al pie

const func = () => {
  return new Promise((resolve, reject) => {
    setImmediate(() => {
      throw new Error('foo');
    });
  });
};
const main = async () => {
  try {
    await func();
  } catch (ex) {
    console.log('will not execute');
  }
};
main();

  1. La gente a veces escribe un c√≥digo como este cuando quiere manejar el error as√≠ncrono invocando la funci√≥n callback y pasando el error como un argumento. Pero cometen el error de pensar que si lo lanzan desde su propia devoluci√≥n de llamada (la funci√≥n pas√≥ a doSomeAsynchronousOperation ), entonces se puede capturar en el catch < / c√≥digo> bloque. No es as√≠ como try / catch funciona con funciones as√≠ncronas. Recuerde que todo el punto de una funci√≥n asincr√≥nica es que se invoca alg√ļn tiempo m√°s tarde , despu√©s de que myApiFunc vuelva. Eso significa que se ha salido del bloque try . La devoluci√≥n de llamada es invocada directamente por Node, sin  intente bloquear a su alrededor. Por lo tanto, si usa este anti-patr√≥n, terminar√° fallando el programa cuando lance el error. Evento en el caso de una funci√≥n async expl√≠cita que utiliza una await en el bloque try , no se detectar√° un error generado de forma as√≠ncrona. A continuaci√≥n se muestra un ejemplo de un error que no se detectar√°. & # 160; & # 8617; < / p> un error lanzado de forma as√≠ncrona no ser√° atrapado. A continuaci√≥n se muestra un ejemplo de un error que no se detectar√°. & # 160; & # 8617; < / p> un error lanzado de forma as√≠ncrona no ser√° atrapado. A continuaci√≥n se muestra un ejemplo de un error que no se detectar√°. & # 160; & # 8617; < / p>
  2. En JavaScript, t√©cnicamente puedes lanzar cosas que no son Errores, pero esto deber√≠a evitarse. El resultado no incluye el potencial para obtener una pila de llamadas, ni un & quot; nombre & quot; propiedad para inspecci√≥n program√°tica, ni propiedades √ļtiles que describan lo que sali√≥ mal. & # 160; & # 8617; < / p>
  3. Los conceptos de un error operacional y un error de programador son anteriores al Node.js. En Java, esto rastrea el uso de excepciones marcadas y no controladas, aunque los errores operacionales que se sabe que son imposibles de manejar, como OutOfMemoryError , se agrupan con excepciones no verificadas. En C, es an√°logo al manejo normal de errores en comparaci√≥n con el uso de una aserci√≥n, y el art√≠culo de Wikipedia sobre aserciones tiene un similar explicaci√≥n de cu√°ndo usar aserciones frente al manejo normal de errores . & # 160; & # 8617; </ a >
  4. Si eso suena extra√Īamente espec√≠fico, es porque hemos visto esto en producci√≥n. Y fue terrible. & # 160; & # 8617;

Deseas conocer nuestros servicios visita: https://www.wolfpress.co/

Quieres conocer m√°s de nuestra informaci√≥n visita: https://www.wolfpress.co/blog/

Recommended
En varias oportunidades hemos hablado sobre la importancia del error…
Cresta Posts Box by CP