Una guía definitiva para manejar errores en JavaScript
La ley de Murphy establece que cualquier cosa que pueda salir mal eventualmente saldrá mal. Esto se aplica demasiado bien en el mundo de la programación. Si crea una aplicación, es probable que cree errores y otros problemas. ¡Los errores en JavaScript son uno de esos problemas comunes!
El éxito de un producto de software depende de qué tan bien sus creadores puedan resolver estos problemas antes de perjudicar a sus usuarios. Y JavaScript, de todos los lenguajes de programación, es conocido por su diseño promedio de manejo de errores.
Si está creando una aplicación de JavaScript, existe una alta probabilidad de que se equivoque con los tipos de datos en un momento u otro. Si no es así, entonces podría terminar reemplazando un indefinido con un nulo o un operador triple igual (===) con un operador doble igual (==).
Es humano cometer errores. Es por eso que le mostraremos todo lo que necesita saber sobre el manejo de errores en JavaScript.
Este artículo lo guiará a través de los errores básicos en JavaScript y explicará los diversos errores que puede encontrar. A continuación, aprenderá a identificar y corregir estos errores. También hay un par de consejos para manejar los errores de manera efectiva en entornos de producción.
Sin más preámbulos, ¡comencemos!
¿Qué son los errores de JavaScript?
Los errores de programación se refieren a situaciones que no permiten que un programa funcione normalmente. Puede suceder cuando un programa no sabe cómo manejar el trabajo en cuestión, como cuando intenta abrir un archivo inexistente o se comunica con un punto final de API basado en la web mientras no hay conectividad de red.
Estas situaciones empujan al programa a arrojar errores al usuario, indicando que no sabe cómo proceder. El programa recopila la mayor cantidad de información posible sobre el error y luego informa que no puede avanzar.
Los programadores inteligentes intentan predecir y cubrir estos escenarios para que el usuario no tenga que descifrar un mensaje de error técnico como «404» de forma independiente. En cambio, muestran un mensaje mucho más comprensible: “No se pudo encontrar la página”.
Los errores en JavaScript son objetos que se muestran cada vez que ocurre un error de programación. Estos objetos contienen amplia información sobre el tipo de error, la declaración que causó el error y el seguimiento de la pila cuando ocurrió el error. JavaScript también permite a los programadores crear errores personalizados para proporcionar información adicional al depurar problemas.
Propiedades de un error
Ahora que la definición de un error de JavaScript está clara, es hora de profundizar en los detalles.
Los errores en JavaScript tienen ciertas propiedades estándar y personalizadas que ayudan a comprender la causa y los efectos del error. Por defecto, los errores en JavaScript contienen tres propiedades:
- mensaje: un valor de cadena que lleva el mensaje de error
- nombre: El tipo de error que ocurrió (Profundizaremos en esto en la siguiente sección)
- apilar: El seguimiento de la pila del código ejecutado cuando ocurrió el error.
Además, los errores también pueden tener propiedades como número de columna, número de línea, nombre de archivo, etc., para describir mejor el error. Sin embargo, estas propiedades no son estándar y pueden o no estar presentes en todos los objetos de error generados desde su aplicación de JavaScript.
Comprender el seguimiento de la pila
Un seguimiento de pila es la lista de llamadas a métodos en las que se encontraba un programa cuando ocurre un evento como una excepción o una advertencia. Así es como se ve un rastro de pila de muestra acompañado de una excepción:

Como puede ver, comienza imprimiendo el nombre y el mensaje del error, seguido de una lista de métodos que se estaban llamando. Cada llamada de método indica la ubicación de su código fuente y la línea en la que se invocó. Puede usar estos datos para navegar a través de su base de código e identificar qué fragmento de código está causando el error.
Esta lista de métodos está organizada de forma apilada. Muestra dónde se lanzó por primera vez su excepción y cómo se propagó a través de las llamadas a métodos apilados. La implementación de una captura para la excepción no permitirá que se propague a través de la pila y bloquee su programa. Sin embargo, es posible que desee dejar los errores fatales sin detectar para bloquear el programa en algunos escenarios intencionalmente.
Errores frente a excepciones
La mayoría de la gente suele considerar los errores y las excepciones como la misma cosa. Sin embargo, es esencial tener en cuenta una diferencia leve pero fundamental entre ellos.
Para entender esto mejor, tomemos un ejemplo rápido. Así es como puede definir un error en JavaScript:
const wrongTypeError = TypeError("Wrong type found, expected character")
Y así es como el wrongTypeError objeto se convierte en una excepción:
throw wrongTypeError
Sin embargo, la mayoría de la gente tiende a usar la forma abreviada que define los objetos de error mientras los lanza:
throw TypeError("Wrong type found, expected character")
Esta es una práctica estándar. Sin embargo, es una de las razones por las que los desarrolladores tienden a mezclar excepciones y errores. Por lo tanto, conocer los fundamentos es vital, aunque use taquigrafía para hacer su trabajo rápidamente.
Tipos de errores en JavaScript
Hay una variedad de tipos de errores predefinidos en JavaScript. Son elegidos y definidos automáticamente por el tiempo de ejecución de JavaScript siempre que el programador no maneje explícitamente los errores en la aplicación.
Esta sección lo guiará a través de algunos de los tipos de errores más comunes en JavaScript y comprenderá cuándo y por qué ocurren.
RangeError
Se lanza un RangeError cuando una variable se establece con un valor fuera de su rango de valores legales. Por lo general, ocurre cuando se pasa un valor como argumento a una función y el valor dado no se encuentra en el rango de los parámetros de la función. A veces puede resultar complicado solucionarlo cuando se utilizan bibliotecas de terceros mal documentadas, ya que necesita conocer el rango de valores posibles para que los argumentos pasen el valor correcto.
Algunos de los escenarios comunes en los que se produce RangeError son:
- Intentando crear una matriz de longitudes ilegales a través del constructor Array.
- Pasar valores incorrectos a métodos numéricos como
toExponential(),toPrecision(),toFixed(), etc - Pasar valores ilegales a funciones de cadena como
normalize().
Error de referencia
Un ReferenceError ocurre cuando algo está mal con la referencia de una variable en su código. Es posible que haya olvidado definir un valor para la variable antes de usarla o que esté tratando de usar una variable inaccesible en su código. En cualquier caso, pasar por el seguimiento de la pila proporciona amplia información para encontrar y corregir la referencia de la variable que tiene la culpa.
Algunas de las razones comunes por las que se producen los errores de referencia son:
- Hacer un error tipográfico en un nombre de variable.
- Intentar acceder a variables de ámbito de bloque fuera de sus ámbitos.
- Hacer referencia a una variable global de una biblioteca externa (como $ de jQuery) antes de que se cargue.
Error de sintaxis
Estos errores son de los más sencillos de solucionar ya que indican un error en la sintaxis del código. Dado que JavaScript es un lenguaje de secuencias de comandos que se interpreta en lugar de compilar, estos se lanzan cuando la aplicación ejecuta la secuencia de comandos que contiene el error. En el caso de lenguajes compilados, dichos errores se identifican durante la compilación. Por lo tanto, los archivos binarios de la aplicación no se crean hasta que se corrigen.
Algunas de las razones comunes por las que pueden ocurrir SyntaxErrors son:
- Faltan comillas
- Faltan paréntesis de cierre
- Alineación incorrecta de llaves u otros caracteres
Es una buena práctica usar una herramienta de pelusa en su IDE para identificar dichos errores antes de que lleguen al navegador.
Error de tecleado
TypeError es uno de los errores más comunes en las aplicaciones de JavaScript. Este error se crea cuando algún valor no resulta ser de un tipo esperado en particular. Algunos de los casos comunes cuando ocurre son:
- Invocar objetos que no son métodos.
- Intentar acceder a las propiedades de objetos nulos o indefinidos
- Tratar una cadena como un número o viceversa
Hay muchas más posibilidades en las que puede ocurrir un TypeError. Veremos algunos casos famosos más adelante y aprenderemos a solucionarlos.
Error interno
El tipo InternalError se utiliza cuando se produce una excepción en el motor de tiempo de ejecución de JavaScript. Puede o no indicar un problema con su código.
La mayoría de las veces, InternalError ocurre solo en dos escenarios:
- Cuando un parche o una actualización del tiempo de ejecución de JavaScript tiene un error que arroja excepciones (esto sucede muy raramente)
- Cuando su código contiene entidades que son demasiado grandes para el motor de JavaScript (por ejemplo, demasiado muchos casos de cambio, inicializadores de matriz demasiado grandes, demasiada recursividad)
El enfoque más apropiado para resolver este error es identificar la causa a través del mensaje de error y reestructurar la lógica de la aplicación, si es posible, para eliminar el aumento repentino de la carga de trabajo en el motor de JavaScript.
URIError
URIError ocurre cuando una función de manejo de URI global como decodeURIComponent se usa ilegalmente. Por lo general, indica que el parámetro pasado a la llamada al método no se ajustaba a los estándares de URI y, por lo tanto, el método no lo analizó correctamente.
El diagnóstico de estos errores suele ser fácil, ya que solo necesita examinar los argumentos de malformación.
EvalError
Un EvalError ocurre cuando ocurre un error con un eval() Llamada de función. El eval() La función se utiliza para ejecutar código JavaScript almacenado en cadenas. Sin embargo, dado que se usa el eval() La función está muy desaconsejada debido a problemas de seguridad y las especificaciones actuales de ECMAScript no lanzan el EvalError class, este tipo de error existe simplemente para mantener la compatibilidad con el código JavaScript heredado.
Si está trabajando en una versión anterior de JavaScript, es posible que encuentre este error. En cualquier caso, lo mejor es investigar el código ejecutado en el eval() llamada de función para cualquier excepción.
Creación de tipos de error personalizados
Si bien JavaScript ofrece una lista adecuada de clases de tipos de error para cubrir la mayoría de los escenarios, siempre puede crear un nuevo tipo de error si la lista no satisface sus requisitos. La base de esta flexibilidad radica en el hecho de que JavaScript le permite lanzar cualquier cosa literalmente con el throw mando.
Entonces, técnicamente, estas declaraciones son completamente legales:
throw 8
throw "An error occurred"
Sin embargo, arrojar un tipo de datos primitivo no proporciona detalles sobre el error, como su tipo, nombre o el seguimiento de la pila que lo acompaña. Para arreglar esto y estandarizar el proceso de manejo de errores, el Error se ha proporcionado la clase. También se desaconseja usar tipos de datos primitivos al generar excepciones.
Puedes extender el Error class para crear su clase de error personalizada. Aquí hay un ejemplo básico de cómo puedes hacer esto:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
Y puedes usarlo de la siguiente manera:
throw ValidationError("Property not found: name")
Y luego puede identificarlo usando el instanceof palabra clave:
try {
validateForm() // code that throws a ValidationError
} catch (e) {
if (e instanceof ValidationError)
// do something
else
// do something else
}
Los 10 errores más comunes en JavaScript
Ahora que comprende los tipos de errores comunes y cómo crear los personalizados, es hora de ver algunos de los errores más comunes que enfrentará al escribir código JavaScript.
1. RangeError no detectado
Este error ocurre en Google Chrome en algunos escenarios diferentes. Primero, puede suceder si llama a una función recursiva y no termina. Puedes comprobarlo tú mismo en Chrome Developer Console:

Entonces, para resolver tal error, asegúrese de definir correctamente los casos límite de su función recursiva. Otra razón por la que ocurre este error es si ha pasado un valor que está fuera del rango del parámetro de una función. Aquí hay un ejemplo:

El mensaje de error generalmente indicará qué está mal con su código. Una vez que realice los cambios, se resolverá.

2. TypeError no detectado: no se puede establecer la propiedad
Este error ocurre cuando establece una propiedad en una referencia indefinida. Puede reproducir el problema con este código:
var list
list.count = 0
Este es el resultado que recibirá:

Para corregir este error, inicialice la referencia con un valor antes de acceder a sus propiedades. Así es como se ve cuando se arregla:

3. TypeError no capturado: no se puede leer la propiedad
Este es uno de los errores más frecuentes en JavaScript. Este error ocurre cuando intenta leer una propiedad o llamar a una función en un objeto indefinido. Puede reproducirlo muy fácilmente ejecutando el siguiente código en una consola de Chrome Developer:
var func
func.call()
Aquí está la salida:

Un objeto indefinido es una de las muchas posibles causas de este error. Otra causa importante de este problema puede ser una inicialización incorrecta del estado al representar la interfaz de usuario. Aquí hay un ejemplo del mundo real de una aplicación React:
import React, { useState, useEffect } from "react";
const CardsList = () => {
const [state, setState] = useState();
useEffect(() => {
setTimeout(() => setState({ items: ["Card 1", "Card 2"] }), 2000);
}, []);
return (
<>
{state.items.map((item) => (
<li key={item}>{item}</li>
))}
</>
);
};
export default CardsList;
La aplicación comienza con un contenedor de estado vacío y recibe algunos elementos después de un retraso de 2 segundos. El retardo se establece para imitar una llamada de red. Incluso si su red es súper rápida, aún enfrentará una pequeña demora debido a que el componente se procesará al menos una vez. Si intenta ejecutar esta aplicación, recibirá el siguiente error:

Esto se debe a que, en el momento de la representación, el contenedor de estado no está definido; por lo tanto, no existe propiedad items en eso. Reparar este error es fácil. Solo necesita proporcionar un valor predeterminado inicial al contenedor de estado.
// ...
const [state, setState] = useState({items: []});
// ...
Ahora, después del retraso establecido, su aplicación mostrará un resultado similar:

La solución exacta en su código puede ser diferente, pero la esencia aquí es siempre inicializar sus variables correctamente antes de usarlas.
4. TypeError: ‘indefinido’ no es un objeto
Este error ocurre en Safari cuando intenta acceder a las propiedades o llamar a un método en un objeto no definido. Puede ejecutar el mismo código anterior para reproducir el error usted mismo.

La solución a este error también es la misma: asegúrese de haber inicializado sus variables correctamente y que no estén indefinidas cuando se accede a una propiedad o método.
5. TypeError: null no es un objeto
Esto es, de nuevo, similar al error anterior. Ocurre en Safari, y la única diferencia entre los dos errores es que este se lanza cuando el objeto cuya propiedad o método se está accediendo es null en vez de undefined. Puede reproducir esto ejecutando el siguiente fragmento de código:
var func = null
func.call()
Este es el resultado que recibirá:

Ya que null es un valor establecido explícitamente en una variable y JavaScript no lo asigna automáticamente. Este error solo puede ocurrir si está intentando acceder a una variable que configuró null por tí mismo. Por lo tanto, debe revisar su código y verificar si la lógica que escribió es correcta o no.
6. TypeError: no se puede leer la propiedad ‘longitud’
Este error ocurre en Chrome cuando intentas leer la longitud de un null o undefined objeto. La causa de este problema es similar a los problemas anteriores, pero ocurre con bastante frecuencia al manejar listas; por lo que merece una mención especial. Así es como puede reproducir el problema:

Sin embargo, en las versiones más recientes de Chrome, este error se informa como Uncaught TypeError: Cannot read properties of undefined. Asi es como luce ahora:

La solución, nuevamente, es asegurarse de que el objeto a cuya longitud está tratando de acceder exista y no esté configurado en null.
7. TypeError: ‘indefinido’ no es una función
Este error ocurre cuando intenta invocar un método que no existe en su secuencia de comandos, o existe, pero no se puede hacer referencia en el contexto de la llamada. Este error suele ocurrir en Google Chrome, y puedes solucionarlo comprobando la línea de código que arroja el error. Si encuentra un error tipográfico, arréglelo y compruebe si resuelve tu problema.
Si ha utilizado la palabra clave autorreferencial this en su código, este error podría surgir si this no está apropiadamente ligado a su contexto. Considere el siguiente código:
function showAlert() {
alert("message here")
}
document.addEventListener("click", () => {
this.showAlert();
})
Si ejecuta el código anterior, arrojará el error que discutimos. Ocurre porque la función anónima pasada como detector de eventos se está ejecutando en el contexto del document.
En cambio, la función showAlert se define en el contexto de la window.
Para resolver esto, debe pasar la referencia adecuada a la función vinculándola con el bind() método:
document.addEventListener("click", this.showAlert.bind(this))
8. ReferenceError: el evento no está definido
Este error ocurre cuando intenta acceder a una referencia no definida en el alcance de la llamada. Esto suele suceder cuando se manejan eventos, ya que a menudo le brindan una referencia llamada event en la función de devolución de llamada. Este error puede ocurrir si olvida definir el argumento del evento en los parámetros de su función o lo escribe mal.
Es posible que este error no ocurra en Internet Explorer o Google Chrome (ya que IE ofrece una variable de evento global y Chrome adjunta la variable de evento automáticamente al controlador), pero puede ocurrir en Firefox. Por lo tanto, es recomendable estar atento a errores tan pequeños.
9. TypeError: Asignación a variable constante
Este es un error que surge por descuido. Si intenta asignar un nuevo valor a una variable constante, se encontrará con este resultado:

Si bien parece fácil de arreglar en este momento, imagine cientos de declaraciones de variables de este tipo y una de ellas definida erróneamente como const en vez de let! A diferencia de otros lenguajes de secuencias de comandos como PHP, existe una diferencia mínima entre el estilo de declaración de constantes y variables en JavaScript. Por lo tanto, es recomendable verificar sus declaraciones en primer lugar cuando se encuentre con este error. También podría encontrarse con este error si olvidar que dicha referencia es una constante y utilizarla como variable. Esto indica descuido o una falla en la lógica de su aplicación. Asegúrese de marcar esto cuando intente solucionar este problema.
10. (desconocido): error de secuencia de comandos
Un error de secuencia de comandos ocurre cuando una secuencia de comandos de terceros envía un error a su navegador. Este error es seguido por (desconocido) porque el script de terceros pertenece a un dominio diferente al de su aplicación. El navegador oculta otros detalles para evitar la filtración de información confidencial del script de terceros.
No puede resolver este error sin conocer los detalles completos. Esto es lo que puede hacer para obtener más información sobre el error:
- Añade el
crossoriginatributo en la etiqueta del script. - Establecer el correcto
Access-Control-Allow-Originencabezado en el servidor que aloja el script. - [Optional] Si no tiene acceso al servidor que aloja el script, puede considerar usar un proxy para transmitir su solicitud al servidor y al cliente con los encabezados correctos.
Una vez que pueda acceder a los detalles del error, puede establecerse para solucionar el problema, que probablemente estará en la biblioteca de terceros o en la red.
Cómo identificar y prevenir errores en JavaScript
Si bien los errores discutidos anteriormente son los más comunes y frecuentes en JavaScript, se encontrará con que confiar en algunos ejemplos nunca puede ser suficiente. Es vital comprender cómo detectar y prevenir cualquier tipo de error en una aplicación de JavaScript mientras se desarrolla. Así es como puede manejar los errores en JavaScript.
Lanzar y atrapar errores manualmente
La forma más fundamental de manejar los errores que se han producido manualmente o por el tiempo de ejecución es detectarlos. Como la mayoría de los otros lenguajes, JavaScript ofrece un conjunto de palabras clave para manejar errores. Es esencial conocer cada uno de ellos en profundidad antes de comenzar a manejar los errores en su aplicación de JavaScript.
lanzar
La primera y más básica palabra clave del conjunto es throw. Como es evidente, la palabra clave throw se utiliza para generar errores para crear excepciones en el tiempo de ejecución de JavaScript de forma manual. Ya hemos discutido esto anteriormente en el artículo, y aquí está la esencia del significado de esta palabra clave:
- Usted puede
throwcualquier cosa, incluidos números, cadenas yErrorobjetos. - Sin embargo, no es recomendable arrojar tipos de datos primitivos, como cadenas y números, ya que no contienen información de depuración sobre los errores.
- Ejemplo:
throw TypeError("Please provide a string")
tratar
El try La palabra clave se utiliza para indicar que un bloque de código puede generar una excepción. Su sintaxis es:
try {
// error-prone code here
}
Es importante notar que un catch bloque siempre debe seguir el try bloque para manejar los errores de manera efectiva.
captura
El catch La palabra clave se utiliza para crear un bloque catch. Este bloque de código es responsable de manejar los errores que el seguimiento try capturas de bloque. Aquí está su sintaxis:
catch (exception) {
// code to handle the exception here
}
Y así es como se implementa el try y el catch bloques juntos:
try {
// business logic code
} catch (exception) {
// error handling code
}
A diferencia de C++ o Java, no puede agregar múltiples catch bloques a un try bloque en JavaScript. Esto significa que no puedes hacer esto:
try {
// business logic code
} catch (exception) {
if (exception instanceof TypeError) {
// do something
}
} catch (exception) {
if (exception instanceof RangeError) {
// do something
}
}
En su lugar, puede utilizar un if...else declaración o una declaración de cambio de caso dentro del bloque catch único para manejar todos los casos de error posibles. Se vería así:
try {
// business logic code
} catch (exception) {
if (exception instanceof TypeError) {
// do something
} else if (exception instanceof RangeError) {
// do something else
}
}
por fin
El finally La palabra clave se utiliza para definir un bloque de código que se ejecuta después de que se ha manejado un error. Este bloque se ejecuta después de los bloques try y catch.
Además, el bloque finalmente se ejecutará independientemente del resultado de los otros dos bloques. Esto significa que incluso si el bloque catch no puede manejar el error por completo o si se arroja un error en el bloque catch, el intérprete ejecutará el código en el último bloque antes de que el programa se bloquee.
Para que se considere válido, el bloque de prueba en JavaScript debe ir seguido de un bloque de captura o finalmente. Sin ninguno de ellos, el intérprete generará un SyntaxError. Por lo tanto, asegúrese de seguir sus bloques de prueba con al menos cualquiera de ellos cuando maneje errores.
Manejar errores globalmente con el método onerror()
El onerror() El método está disponible para todos los elementos HTML para manejar cualquier error que pueda ocurrir con ellos. Por ejemplo, si un img la etiqueta no puede encontrar la imagen cuya URL se especifica, activa su método onerror para permitir que el usuario maneje el error.
Por lo general, proporcionaría otra URL de imagen en la llamada onerror para el img etiqueta a la que recurrir. Así es como puedes hacerlo a través de JavaScript:
const image = document.querySelector("img")
image.onerror = (event) => {
console.log("Error occurred: " + event)
}
Sin embargo, puede usar esta característica para crear un mecanismo global de manejo de errores para su aplicación. Así es como puedes hacerlo:
window.onerror = (event) => {
console.log("Error occurred: " + event)
}
Con este controlador de eventos, puede deshacerse de los múltiples try...catch bloques que se encuentran en su código y centralicen el manejo de errores de su aplicación de manera similar al manejo de eventos. Puede adjuntar varios controladores de errores a la ventana para mantener el principio de responsabilidad única de los principios de diseño de SOLID. El intérprete recorrerá todos los controladores hasta que llegue al apropiado.
Pasar errores a través de devoluciones de llamada
Si bien las funciones simples y lineales permiten que el manejo de errores siga siendo simple, las devoluciones de llamadas pueden complicar el asunto.
Considere la siguiente pieza de código:
const calculateCube = (number, callback) => {
setTimeout(() => {
const cube = number * number * number
callback(cube)
}, 1000)
}
const callback = result => console.log(result)
calculateCube(4, callback)
La función anterior demuestra una condición asincrónica en la que una función tarda un tiempo en procesar las operaciones y devuelve el resultado más tarde con la ayuda de una devolución de llamada.
Si intenta ingresar una cadena en lugar de 4 en la llamada de función, obtendrá NaN como resultado.
Esto debe manejarse adecuadamente. Así es cómo:
const calculateCube = (number, callback) => {
setTimeout(() => {
if (typeof number !== "number")
throw new Error("Numeric argument is expected")
const cube = number * number * number
callback(cube)
}, 1000)
}
const callback = result => console.log(result)
try {
calculateCube(4, callback)
} catch (e) { console.log(e) }
Esto debería resolver el problema idealmente. Sin embargo, si intenta pasar una cadena a la llamada de función, recibirá esto:

Aunque haya implementado un bloque try-catch al llamar a la función, aún dice que el error no se detectó. El error se produce después de que se haya ejecutado el bloque catch debido al retraso del tiempo de espera.
Esto puede ocurrir rápidamente en las llamadas de la red, donde se producen retrasos inesperados. Debe cubrir estos casos mientras desarrolla su aplicación.
Así es como puede manejar los errores correctamente en las devoluciones de llamada:
const calculateCube = (number, callback) => {
setTimeout(() => {
if (typeof number !== "number") {
callback(new TypeError("Numeric argument is expected"))
return
}
const cube = number * number * number
callback(null, cube)
}, 2000)
}
const callback = (error, result) => {
if (error !== null) {
console.log(error)
return
}
console.log(result)
}
try {
calculateCube('hey', callback)
} catch (e) {
console.log(e)
}
Ahora, la salida en la consola será:

Esto indica que el error ha sido manejado apropiadamente.
Manejar errores en promesas
La mayoría de las personas tienden a preferir las promesas para manejar actividades asincrónicas. Las promesas tienen otra ventaja: una promesa rechazada no finaliza su script. Sin embargo, aún necesita implementar un bloque catch para manejar los errores en las promesas. Para entender esto mejor, reescribamos el calculateCube() función usando Promesas:
const delay = ms => new Promise(res => setTimeout(res, ms));
const calculateCube = async (number) => {
if (typeof number !== "number")
throw Error("Numeric argument is expected")
await delay(5000)
const cube = number * number * number
return cube
}
try {
calculateCube(4).then(r => console.log(r))
} catch (e) { console.log(e) }
El tiempo de espera del código anterior se ha aislado en el delay Función para la comprensión. Si intenta ingresar una cadena en lugar de 4, el resultado que obtendrá será similar a este:

De nuevo, esto se debe a la Promise lanzando el error después de que todo lo demás haya completado la ejecución. La solución a este problema es simple. Simplemente agregue un catch() llama a la cadena de promesas así:
calculateCube("hey")
.then(r => console.log(r))
.catch(e => console.log(e))
Ahora la salida será:

Puede observar lo fácil que es manejar errores con promesas. Además, puede encadenar un finally() bloque y la llamada de promesa para agregar código que se ejecutará después de que se haya completado el manejo de errores.
Alternativamente, también puede manejar los errores en las promesas usando la técnica tradicional de intentar-atrapar-finalmente. Así es como se vería tu llamada de promesa en ese caso:
try {
let result = await calculateCube("hey")
console.log(result)
} catch (e) {
console.log(e)
} finally {
console.log('Finally executed")
}
Sin embargo, esto funciona solo dentro de una función asíncrona. Por lo tanto, la forma preferida de manejar los errores en las promesas es encadenar catch y finally a la llamada de la promesa.
throw/catch vs onerror() vs Callbacks vs Promises: ¿Cuál es el mejor?
Con cuatro métodos a su disposición, debe saber elegir el más adecuado en cualquier caso de uso. Así es como pueden decidir por sí mismos:
lanzar/atrapar
Usará este método la mayor parte del tiempo. Asegúrese de implementar condiciones para todos los errores posibles dentro de su bloque catch y recuerde incluir un bloque finalmente si necesita ejecutar algunas rutinas de limpieza de memoria después del bloque try.
Sin embargo, demasiados bloques try/catch pueden hacer que su código sea difícil de mantener. Si se encuentra en tal situación, es posible que desee manejar los errores a través del controlador global o el método de promesa.
Al decidir entre bloques de prueba/captura asincrónicos y promesas catch(), es recomendable optar por los bloques async try/catch, ya que harán que su código sea lineal y fácil de depurar.
onerror()
Lo mejor es usar el onerror() método cuando sabe que su aplicación tiene que manejar muchos errores, y pueden estar bien dispersos en toda la base de código. El onerror El método le permite manejar los errores como si fueran un evento más manejado por su aplicación. Puede definir varios controladores de errores y adjuntarlos a la ventana de su aplicación en la representación inicial.
Sin embargo, también debe recordar que el onerror() El método puede ser innecesariamente difícil de configurar en proyectos más pequeños con un margen de error menor. Si está seguro de que su aplicación no arrojará demasiados errores, el método tradicional de lanzar/atrapar funcionará mejor para usted.
Devoluciones de llamadas y promesas
El manejo de errores en devoluciones de llamada y promesas difiere debido a su diseño y estructura de código. Sin embargo, si elige entre estos dos antes de haber escrito su código, sería mejor seguir con las promesas.
Esto se debe a que las promesas tienen una construcción incorporada para encadenar un catch() y un finally() block para manejar errores fácilmente. Este método es más fácil y limpio que definir argumentos adicionales/reutilizar argumentos existentes para manejar errores.
Realice un seguimiento de los cambios con los repositorios de Git
A menudo surgen muchos errores debido a errores manuales en la base de código. Mientras desarrolla o depura su código, puede terminar haciendo cambios innecesarios que pueden causar que aparezcan nuevos errores en su base de código. Las pruebas automatizadas son una excelente manera de mantener su código bajo control después de cada cambio. Sin embargo, solo puede decirte si algo anda mal. Si no realiza copias de seguridad frecuentes de su código, terminará perdiendo el tiempo tratando de arreglar una función o un script que funcionaba bien antes.
Aquí es donde git juega su papel. Con una estrategia de confirmación adecuada, puede usar su historial de git como un sistema de respaldo para ver su código a medida que evolucionó a lo largo del desarrollo. Puede navegar fácilmente a través de sus confirmaciones anteriores y descubrir la versión de la función que funcionaba bien antes pero arrojaba errores después de un cambio no relacionado.
Luego puede restaurar el código anterior o comparar las dos versiones para determinar qué salió mal. Las herramientas modernas de desarrollo web como GitHub Desktop o GitKraken lo ayudan a visualizar estos cambios uno al lado del otro y descubrir los errores rápidamente.
Un hábito que puede ayudarlo a cometer menos errores es ejecutar revisiones de código cada vez que realice un cambio significativo en su código. Si está trabajando en un equipo, puede crear una solicitud de extracción y hacer que un miembro del equipo la revise minuciosamente. Esto lo ayudará a usar un segundo par de ojos para detectar cualquier error que se le haya escapado.
Mejores prácticas para manejar errores en JavaScript
Los métodos mencionados anteriormente son adecuados para ayudarlo a diseñar un enfoque sólido de manejo de errores para su próxima aplicación de JavaScript. Sin embargo, sería mejor tener en cuenta algunas cosas al implementarlas para obtener lo mejor de su corrección de errores. Aquí hay algunos consejos para ayudarte.
1. Use errores personalizados al manejar excepciones operativas
Presentamos errores personalizados al principio de esta guía para darle una idea de cómo personalizar el manejo de errores para el caso único de su aplicación. Es recomendable utilizar errores personalizados siempre que sea posible en lugar de los genéricos. Error class ya que proporciona más información contextual al entorno de llamada sobre el error.
Además de eso, los errores personalizados le permiten moderar cómo se muestra un error en el entorno de llamadas. Esto significa que puede optar por ocultar detalles específicos o mostrar información adicional sobre el error cuando lo desee.
Puede llegar a formatear el contenido del error según sus necesidades. Esto le brinda un mejor control sobre cómo se interpreta y maneja el error.
2. No trague ninguna excepción
Incluso los desarrolladores más experimentados a menudo cometen un error de novato: consumen niveles de excepciones en lo más profundo de su código.
Es posible que se encuentre con situaciones en las que tenga un fragmento de código cuya ejecución sea opcional. Si funciona, genial; si no es así, no es necesario que haga nada al respecto.
En estos casos, a menudo es tentador colocar este código en un bloque de prueba y adjuntarle un bloque de captura vacío. Sin embargo, al hacer esto, dejará ese fragmento de código abierto para causar ningún tipo de error y salirse con la suya. Esto puede volverse peligroso si tiene una base de código grande y muchas instancias de construcciones de gestión de errores deficientes.
La mejor manera de manejar las excepciones es determinar un nivel en el que se repartirán todas y elevarlas hasta allí. Este nivel puede ser un controlador (en una aplicación de arquitectura MVC) o un middleware (en una aplicación tradicional orientada a servidor).
De esta manera, sabrá dónde puede encontrar todos los errores que ocurren en su aplicación y elegir cómo resolverlos, incluso si eso significa no hacer nada al respecto.
3. Use una estrategia centralizada para registros y alertas de error
Registrar un error es a menudo una parte integral de su manejo. Quienes no desarrollen una estrategia centralizada para registrar errores pueden perder información valiosa sobre el uso de su aplicación.
Los registros de eventos de una aplicación pueden ayudarlo a descubrir datos cruciales sobre errores y ayudarlo a depurarlos rápidamente. Si tiene los mecanismos de alerta adecuados configurados en su aplicación, puede saber cuándo ocurre un error en su aplicación antes de que llegue a una gran parte de su base de usuarios.
Es recomendable utilizar un registrador prediseñado o crear uno que se adapte a sus necesidades. Puede configurar este registrador para manejar errores en función de sus niveles (advertencia, depuración, información, etc.), y algunos registradores incluso llegan a enviar registros a servidores de registro remotos de inmediato. De esta manera, puede ver cómo funciona la lógica de su aplicación con los usuarios activos.
4. Notificar a los usuarios sobre los errores de manera adecuada
Otro buen punto a tener en cuenta al definir su estrategia de manejo de errores es tener en cuenta al usuario.
Todos los errores que interfieren con el funcionamiento normal de su aplicación deben presentar una alerta visible al usuario para notificarle que algo salió mal para que el usuario pueda intentar encontrar una solución. Si conoce una solución rápida para el error, como volver a intentar una operación o cerrar sesión y volver a iniciar sesión, asegúrese de mencionarlo en la alerta para ayudar a corregir la experiencia del usuario en tiempo real.
En el caso de errores que no causen ninguna interferencia con la experiencia diaria del usuario, puede considerar suprimir la alerta y registrar el error a un servidor remoto para resolverlo más tarde.
5. Implementar un Middleware (Node.js)
El entorno Node.js admite middlewares para agregar funcionalidades a las aplicaciones del servidor. Puede usar esta característica para crear un middleware de manejo de errores para su servidor.
El beneficio más significativo de usar middleware es que todos sus errores se manejan de manera centralizada en un solo lugar. Puede optar por habilitar/deshabilitar esta configuración con fines de prueba fácilmente.
Así es como puede crear un middleware básico:
const logError = err => {
console.log("ERROR: " + String(err))
}
const errorLoggerMiddleware = (err, req, res, next) => {
logError(err)
next(err)
}
const returnErrorMiddleware = (err, req, res, next) => {
res.status(err.statusCode || 500)
.send(err.message)
}
module.exports = {
logError,
errorLoggerMiddleware,
returnErrorMiddleware
}
Luego puede usar este middleware en su aplicación de esta manera:
const { errorLoggerMiddleware, returnErrorMiddleware } = require('./errorMiddleware')
app.use(errorLoggerMiddleware)
app.use(returnErrorMiddleware)
Ahora puede definir una lógica personalizada dentro del middleware para manejar los errores de manera adecuada. Ya no necesita preocuparse por implementar construcciones de manejo de errores individuales en su base de código.
6. Reinicie su aplicación para manejar los errores del programador (Node.js)
Cuando las aplicaciones de Node.js encuentran errores del programador, es posible que no generen necesariamente una excepción e intenten cerrar la aplicación. Dichos errores pueden incluir problemas derivados de errores del programador, como un alto consumo de CPU, una sobrecarga de memoria o pérdidas de memoria. La mejor manera de manejar esto es reiniciar correctamente la aplicación bloqueándola a través del modo de clúster de Node.js o una herramienta única como PM2. Esto puede garantizar que la aplicación no se bloquee con la acción del usuario, presentando una experiencia de usuario terrible.
7. Captura todas las excepciones no detectadas (Node.js)
Nunca puede estar seguro de haber cubierto todos los posibles errores que pueden ocurrir en su aplicación. Por lo tanto, es esencial implementar una estrategia alternativa para capturar todas las excepciones no detectadas de su aplicación.
Así es como puedes hacer eso:
process.on('uncaughtException', error => {
console.log("ERROR: " + String(error))
// other handling mechanisms
})
También puede identificar si el error que ocurrió es una excepción estándar o un error operativo personalizado. Según el resultado, puede salir del proceso y reiniciarlo para evitar un comportamiento inesperado.
8. Captura todos los rechazos de promesas no manejados (Node.js)
De manera similar a cómo nunca puede cubrir todas las posibles excepciones, existe una alta probabilidad de que se pierda el manejo de todos los posibles rechazos de promesas. Sin embargo, a diferencia de las excepciones, los rechazos de promesas no arrojan errores.
Por lo tanto, una promesa importante que fue rechazada podría pasar desapercibida como una advertencia y dejar su aplicación abierta a la posibilidad de encontrarse con un comportamiento inesperado. Por lo tanto, es crucial implementar un mecanismo alternativo para manejar el rechazo de promesas.
Así es como puedes hacer eso:
const promiseRejectionCallback = error => {
console.log("PROMISE REJECTED: " + String(error))
}
process.on('unhandledRejection', callback)
Resumen
Como cualquier otro lenguaje de programación, los errores son bastante frecuentes y naturales en JavaScript. En algunos casos, es posible que incluso deba arrojar errores intencionalmente para indicar la respuesta correcta a sus usuarios. Por lo tanto, comprender su anatomía y tipos es muy importante.
Además, debe estar equipado con las herramientas y técnicas adecuadas para identificar y evitar que los errores eliminen su aplicación.
En la mayoría de los casos, una estrategia sólida para manejar los errores con una ejecución cuidadosa es suficiente para todos los tipos de aplicaciones de JavaScript.
¿Hay algún otro error de JavaScript que aún no hayas podido resolver? ¿Alguna técnica para manejar los errores de JS de manera constructiva? ¡Háganos saber en los comentarios a continuación!
Ahorre tiempo, costos y maximice el rendimiento del sitio con:
- Ayuda instantánea de expertos en alojamiento de WordPress, 24/7.
- Integración empresarial de Cloudflare.
- Alcance de audiencia global con 29 centros de datos en todo el mundo.
- Optimización con nuestro monitoreo de rendimiento de aplicaciones integrado.
Todo eso y mucho más, en un solo plan sin contratos a largo plazo, migraciones asistidas y una garantía de devolución de dinero de 30 días. Consulte nuestros planes o hable con ventas para encontrar el plan adecuado para usted.
