W3docs

Errores Personalizados en JavaScript

JavaScript permite crear tipos de error propios extendiendo la clase Error integrada, lo que habilita un manejo de errores más detallado y preciso.

Errores Personalizados en JavaScript

JavaScript te permite crear tus propios tipos de error extendiendo la clase Error integrada. Un error personalizado es simplemente una clase que hereda de Error (u otro tipo de error) y lleva un name significativo más cualquier dato adicional que la situación requiera.

Esta página explica por qué querrías usar errores personalizados, cómo definirlos correctamente, cómo distinguir tipos de error con instanceof, cómo adjuntar contexto (códigos de estado, nombres de campo, el cause original) y cómo organizar una jerarquía de errores para una aplicación real.

¿Por qué crear errores personalizados?

Lanzar un simple new Error("...") funciona, pero solo le entrega al código que lo llama un string para inspeccionar. Los errores personalizados resuelven tres problemas:

  • Manejo basado en tipos. Con instanceof ValidationError puedes reaccionar ante un tipo concreto de fallo sin analizar el texto del mensaje, lo cual es frágil y depende del idioma.
  • Contexto adicional. Una clase personalizada puede llevar campos estructurados — un statusCode HTTP, el field infractor, una sugerencia de reintento — en lugar de comprimir todo en el mensaje.
  • Jerarquías claras. Una clase base compartida (por ejemplo AppError) permite que un manejador de nivel superior capture todos los errores de tu aplicación con un único instanceof, mientras el código interno puede lanzar subtipos específicos.

Si solo necesitas aprender primero la mecánica de lanzar y capturar, lee Manejo de errores: try...catch. Los errores personalizados se construyen directamente sobre la herencia de clases y la extensión de clases integradas.

Bases para Extender la Clase Error

Para crear un error personalizado, usas extend en la clase Error. La nueva clase hereda message, stack y toString() de Error, y tú agregas lo que necesites.

Crear una Clase de Error Personalizada

Este es el patrón mínimo:

class ValidationError extends Error {
  constructor(message) {
    super(message);  // Pass the message to the Error constructor (sets this.message)
    this.name = "ValidationError";  // Override the default name "Error"
  }
}

Dos detalles importan:

  • super(message) debe ir primero. Dentro del constructor de una subclase no puedes usar this antes de llamar a super(). El constructor de Error establece this.message y captura el stack trace.
  • Establece this.name. Sin él, el error se reporta como "Error" en los mensajes y en toString(). Establecer name hace que los registros y el patrón switch (error.name) sean legibles.

También puedes ver Object.setPrototypeOf(this, new.target.prototype) en algunos ejemplos. Con transpiladores modernos y clases nativas generalmente no es necesario, pero no hace daño y garantiza que instanceof funcione incluso cuando el código se compila a ES5 o se comparte entre entornos (iframes o límites de workers). Los ejemplos a continuación lo conservan por seguridad.

Una vez creado, el error se comporta como cualquier otro:

const e = new ValidationError("bad input");
e.name;               // "ValidationError"
e instanceof Error;   // true  — it is still a real Error
e.toString();         // "ValidationError: bad input"

Usar Errores Personalizados

Una vez que has definido un error personalizado, puedes lanzarlo en tu aplicación como cualquier error estándar:

javascript— editable

En este ejemplo, se valida un correo electrónico contra una expresión regular. Si la validación falla, se lanza un ValidationError. Este error se captura en el bloque try...catch y, si es una instancia de ValidationError, se registra un mensaje específico.

Manejar Múltiples Tipos de Errores Personalizados

Es posible que quieras crear varios tipos de errores para diferentes partes de tu aplicación. Así puedes manejar múltiples errores personalizados:

javascript— editable

Esta estructura permite manejar de forma distinta cada tipo de error, haciendo que la aplicación sea más robusta y fácil de depurar.

Prefiere instanceof sobre comparar strings de error.name cuando puedas: instanceof también coincide con las subclases, por lo que sobrevive mejor a las refactorizaciones.

Construir una Jerarquía de Errores con una Clase Base

En aplicaciones reales vale la pena darle a todos tus errores un ancestro común. Un manejador de nivel superior puede entonces capturar todos los errores "esperados" de la aplicación en un solo lugar, mientras el código más profundo lanza subtipos precisos. La opción cause (ES2022) permite que un error de nivel superior envuelva al de nivel inferior que lo provocó, conservando el original para depuración.

javascript— editable

Aquí this.name = this.constructor.name elimina la necesidad de repetir el nombre en cada subclase, y la única comprobación instanceof AppError captura NotFoundError, ConflictError y cualquier subtipo futuro.

Manejo Avanzado de Errores Personalizados en JavaScript

Ampliando las bases, podemos aplicar errores personalizados a escenarios más complejos como operaciones asíncronas y casos de lógica de negocio específica.

Ejemplo 1: Manejo de Errores de API Personalizado

Este ejemplo muestra cómo crear y usar un error personalizado para manejar problemas en solicitudes de API, como cuando un recurso solicitado no se encuentra o el servidor devuelve un error. El flujo async/await aquí se combina con el manejo de errores con promesas.

javascript— editable

Explicación

  • Clase ApiError: Esta clase personalizada captura errores específicos de la API, almacenando el código de estado HTTP junto con un mensaje personalizado.
  • Función fetchData: Intenta obtener datos de una URL proporcionada. Si la respuesta no es exitosa, lanza un ApiError con un mensaje detallado y el código de estado.
  • Manejo de errores: Los errores se capturan y manejan apropiadamente. Los errores relacionados con la API se registran con información detallada, mientras que los errores inesperados también se capturan y registran.

Ejemplo 2: Manejo de Errores de Validación Personalizado

Usa este ejemplo para manejar errores relacionados con la validación de datos, como la verificación de la entrada del usuario.

javascript— editable

Explicación

  • Clase ValidationError: Una clase de error personalizada que ayuda a identificar qué campo específico de los datos de entrada no superó la validación.
  • Función validateUser: Comprueba la validez de los datos del usuario. Si los datos no cumplen ciertos criterios, lanza un ValidationError.
  • Manejo de errores: Captura los errores de validación y los registra con información detallada. Los demás tipos de errores también se manejan por separado.

Buenas Prácticas y Advertencias

  • Llama siempre a super(message) primero, antes de tocar this.
  • Establece name para que los registros y toString() sean legibles; this.name = this.constructor.name lo hace una sola vez para toda una jerarquía.
  • Prefiere instanceof sobre comparaciones de error.name — también coincide con las subclases.
  • Relanza lo que no reconoces. Un catch que se traga todo (catch (e) {}) oculta errores reales. Maneja tus tipos conocidos y haz throw error para el resto, como hacen los ejemplos.
  • Usa cause para envolver, no para reemplazar. Cuando capturas un error de bajo nivel y lanzas uno de alto nivel, pasa { cause: original } para que el stack trace y la causa raíz sobrevivan.
  • No subclasifiques Error para controlar el flujo. Los errores son para condiciones excepcionales, no para ramificaciones normales.

Conclusión

Crear clases de error personalizadas en JavaScript extendiendo la clase Error es una técnica poderosa para manejar tipos específicos de errores de forma más granular. Mejora la claridad y la mantenibilidad del manejo de errores en tu código, permitiéndote ofrecer comentarios y acciones más específicas según las diferentes condiciones de error. Este método no solo ayuda en la depuración, sino que también mejora la fiabilidad de tus aplicaciones al garantizar que cada tipo de error se capture y maneje adecuadamente.

Práctica

Práctica
¿Cuál es el propósito de usar clases de error extendidas en JavaScript?
¿Cuál es el propósito de usar clases de error extendidas en JavaScript?
Práctica
En el constructor de una subclase de error personalizada, ¿por qué debe llamarse a super(message) antes de usar this?
En el constructor de una subclase de error personalizada, ¿por qué debe llamarse a super(message) antes de usar this?
Práctica
¿Qué permite hacer la opción cause de ES2022 al lanzar un error personalizado?
¿Qué permite hacer la opción cause de ES2022 al lanzar un error personalizado?
Was this page helpful?