Qué son excepciones en Javascript, cómo levantarlas con throw y en qué casos excepcionales deberías lanzar errores en tus aplicaciones.
En Javascript debemos aprender también a manejar errores, levantando las correspondienes señales de error cuando pasan cosas que se escapan de la propia aplicación. Dicho de otro modo, debemos saber lanzar excepciones cuando ocurren cosas excepcionales.
El manejo de errores es una parte esencial en cualquier lenguaje de programación y con JavaScript lo podemos hacer de una manera sencilla a partir de la sentencia throw
que vamos a explicar en este artículo. En resumen veras cómo usar throw
para lanzar errores personalizados, que pueden ser capturados y gestionados de forma controlada por tus propias aplicaciones o cualquer otro desarrollador que use tu software.
¿Qué es throw en JavaScript?
La palabra clave throw
en JavaScript se utiliza para lanzar un error, algo que conocemos también por el término excepción. Una vez que se lanza un error con throw
, el flujo normal del programa se interrumpe, apareciendo generalmente un error en la consola.
Por supuesto, nosotros como desarrolladores también podemos manejar los errores, por medio del tratamiento de excepciones que se consigue con los bloques try
y catch
. Por tanto, cuando ocurre un throw
la ejecución pasa al primer bloque catch
disponible en la cadena de llamadas.
Sintaxis de la sentencia throw
throw expresión;
La expresión puede ser de cualquier tipo: un número, una cadena, un objeto, o una instancia de la clase Error
.
Ejemplo básico
throw "Algo salió mal"; // lanza una excepción con un mensaje que en este caso es de tipo string
throw 404; // lanza una excepción con un valor, que en este caso es numérico
throw new Error("Error inesperado"); // esta es la forma más común y recomendable de lanzar errores, con una instancia de la clase Error
Cómo usar los bloques try...catch para tratar los errores
Como hemos dicho, podemos tratar los errores de manera controlada con las sentencias de manejo de excepciones del lenguaje, try
/ catch
.
Combinando el lanzamiento de errores con bloques try...catch
, podemos capturar y manejar la excepción de forma segura, algo que sirve para que el programa no estalle en la cara del usuario y se detenga la ejecución, mejorando la experiencia de las aplicaciones.
Este sería un código básico de un try...catch
:
try {
throw new Error("Archivo no encontrado");
} catch (e) {
console.error("Se capturó un error:", e.message);
}
Como ves, en el try
podemos capturar los errores, que se tratan en el catch
. En este caso hemos levantado uno de manera explícita con la sentencia throw
, pero podríamos simplemente producirse de manera implícita por algún tipo de error de ejecución del bloque try
.
Puedes encotrar más información sobre este punto en el artículo Cláusulas try … catch: detectar y cazar errores en Javascript.
Ejemplo de levantar un error con una división por cero
Por ejemplo, en un programa podríamos querer levantar un error cuando ocurre una división por cero. Esto generalmente es automático en la mayoría de los lenguaes pero JavaScript sí que permite dividir un número entre 0. En lugar de lanzar una excepción retorna el valor especial Infinity
.
Si deseamos que se levante una excepción lo tenemos que hacer a mano, de manera explícita, con throw
, usando un código como el siguiente:
const division = 40 / 0;
if (!isFinite(division)) {
throw new Error("División por cero no permitida");
}
Ya de paso veamos cómo se debería tratar esta excepción en un bloque try
catch
.
try {
const division = 40 / 0;
if (!isFinite(division)) {
throw new Error("División por cero no permitida");
}
} catch (error) {
console.log("Se produjo un error:", error.message);
}
Tipos de errores en JavaScript
Para que tengas una idea más completa sobre cómo funciona el throw es bueno conocer los tipos de errores que JavaScript proporciona:
Error
: base para todos los errores.TypeError
: cuando se espera un tipo y se obtiene otro.ReferenceError
: cuando se hace referencia a una variable no definida.RangeError
: cuando un valor está fuera de su rango permitido.SyntaxError
: errores de sintaxis en tiempo de compilación.URIError
: errores en funciones de codificación URI.
Ejemplo con TypeError
function dividir(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError("Los argumentos deben ser números");
}
return a / b;
}
Crear errores personalizados
También puedes extender la clase Error
para definir tus propios errores personalizados, que podrían ser más específicos y con mensajes más aclaradores para quien los reciba:
class MiErrorPersonalizado extends Error {
constructor(mensaje) {
super(mensaje);
this.name = "MiErrorPersonalizado";
}
}
throw new MiErrorPersonalizado("Esto es un error hecho a medida");
Buenas prácticas al levantar errores con Javascript
Ya para acabar vamos a ver algunas prácticas que te recomendamos tener en cuenta cuando trabajes con errores en Javascript, tanto a la hora de levantarlos como al tratarlos.
- Usa siempre objetos
Error
o derivados. Evita lanzar cadenas o números simples. - Incluye mensajes claros y útiles para quien reciba el error. Generalmente esos mensajes deberían estar en inglés, ya que el desarrollo se hace en inglés y el error en este caso es una información que tú estás brindando al desarrollador, no al usuario.
- No abuses de
throw
; solo úsalo para condiciones verdaderamente excepcionales. - Ten en cuenta que siempre deberías envolver el código propenso a fallos en bloques
try...catch
.
Qué son condiciones de error "excepcionales"
Quizás te preguntes ¿Qué te referieres con "condiciones verdaderamente excepcionales"? Lo mejor es verlo mediante algunos ejemplos casos típicos en los que deberías levantar un error.
Claro. En programación, una condición excepcional es una situación inesperada o anómala que impide que una función cumpla su contrato o se comporte de forma predecible. No son simplemente "resultados incorrectos", sino estados que rompen una lógica válida o que pueden comprometer el flujo del sistema.
Aquí tienes ejemplos típicos de condiciones excepcionales donde lanzar (throw
) un error tiene sentido:
Fallo en la conexión a un recurso externo
Este es el error más típico: si no puedes conectarte a un servidor externo, o a una base de datos, o cualquier cosa que no dependa de ti, deberías levantar un error, a no ser que quieras tratar tú mismo esa situación en el código de tu conexión.
async function obtenerDatosAPI() {
const respuesta = await fetch('https://api.example.com/data');
if (!respuesta.ok) {
throw new Error("Error al obtener datos de la API");
}
return respuesta.json();
}
Validación de argumentos inválidos
Deberías levantar un error cuando una función recibe argumentos de tipo o valor inesperado:
function calcularAreaCirculo(radio) {
if (typeof radio !== 'number' || radio < 0) {
throw new TypeError("El radio debe ser un número positivo");
}
return Math.PI * radio * radio;
}
División por cero (si tu lógica lo considera inválido)
Esto lo hemos visto antes, pero JS no produce directamente la excepción con una división por cero. Lo tendríamos que levantar nosotros.
Acceso a propiedades obligatorias que no existen
Si tienes un objeto en el que faltan datos necesarios para realizar una operación, puedes levantar un error.
function login(usuario) {
if (!usuario.nombre || !usuario.password) {
throw new Error("Faltan datos obligatorios del usuario");
}
// hacer el login
}
Conclusión
La instrucción throw
no siempre se conoce pero resulta fundamental para que la ejecución del código esté más controlada y segura. Si quieres controlar las situaciones de error las tienes que tratar con bloques try...catch
como hemos visto.
Es fundamental para hacer aplicaciones robustas en Javascript, pero sobre todo es esencial cuando estás desarrollando un software que deberá ser usado por otros módulos de tu aplicación o por otros desarrolladores.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...