WhatsApp

  

Manejo de Errores en JavaScript: Guía Completa de Try / Catch y Buenas Prácticas

Aprende a usar try / catch en JavaScript, compara su uso con promesas y async/await, y descubre patrones avanzados, trucos de depuración y consideraciones de seguridad.

Manejo de Errores en JavaScript: Try / Catch y Más

¿Por qué es esencial el manejo de errores?

En aplicaciones modernas, un error inesperado puede provocar caídas, pérdida de datos o vulnerabilidades de seguridad. Un manejo estructurado permite:

  • Mantener la experiencia de usuario fluida.
  • Registrar información útil para depuración.
  • Prevenir la exposición de datos sensibles.
  • Facilitar la recuperación automática de operaciones críticas.

Sintaxis básica de try / catch

try {
  // Código que puede lanzar una excepción
  const resultado = operacionCritica();
  console.log('Éxito:', resultado);
} catch (error) {
  // Manejo centralizado del error
  console.error('Se produjo un error:', error.message);
}

El bloque finally es opcional y se ejecuta siempre, ideal para liberar recursos.

try {
  // …
} catch (e) {
  // …
} finally {
  // Cierre de conexiones, limpieza de timers, etc.
}

Comparativa rápida (dos columnas)

Try / Catch (síncrono)
  • Captura errores lanzados de forma inmediata.
  • Ideal para código que se ejecuta en el mismo stack.
  • No captura rechazos de promesas sin await o .catch().
  • Puede impactar el rendimiento si se usa en bucles críticos.
Promesas / Async‑Await
  • Los rechazos se manejan con .catch() o try/catch usando await.
  • Mejor para operaciones I/O y llamadas a APIs.
  • Permite encadenar flujos sin anidar bloques try.
  • Requiere atención a errores no manejados (unhandled promise rejections).

Ejemplos prácticos

1️⃣ Validación de entrada con throw

function dividir(a, b) {
  if (b === 0) {
    throw new Error('División por cero no permitida');
  }
  return a / b;
}
try {
  console.log(dividir(10, 0));
} catch (e) {
  console.warn('Operación inválida:', e.message);
}

2️⃣ Manejo de errores en código asíncrono con await

async function obtenerUsuario(id) {
  const respuesta = await fetch(`https://api.example.com/users/${id}`);
  if (!respuesta.ok) {
    throw new Error(`HTTP ${respuesta.status}`);
  }
  return respuesta.json();
}
(async () => {
  try {
    const usuario = await obtenerUsuario(123);
    console.log('Usuario:', usuario);
  } catch (err) {
    console.error('Error al cargar el usuario:', err.message);
  }
})();

3️⃣ Creación de clases de error personalizadas

class ValidationError extends Error {
  constructor(message, campo) {
    super(message);
    this.name = 'ValidationError';
    this.campo = campo;
  }
}
function validarUsuario(usuario) {
  if (!usuario.email.includes('@')) {
    throw new ValidationError('Formato de email inválido', 'email');
  }
}
try {
  validarUsuario({ email: 'bademail' });
} catch (e) {
  if (e instanceof ValidationError) {
    console.log(`Error en campo ${e.campo}: ${e.message}`);
  }
}

Patrones avanzados

  • Retry con backoff exponencial: envolver la lógica en una función que reintente tras fallos transitorios.
  • Decoradores de manejo de errores: usar funciones de orden superior para envolver callbacks y evitar código repetitivo.
  • Captura global: window.onerror y process.on('uncaughtException') para registrar errores no capturados.
function conRetry(fn, intentos = 3, delay = 100) {
  return async (...args) => {
    for (let i = 0; i < intentos; i++) {
      try {
        return await fn(...args);
      } catch (e) {
        if (i === intentos - 1) throw e;
        await new Promise(r => setTimeout(r, delay * 2 ** i)); // backoff
      }
    }
  };
}
const fetchConRetry = conRetry(fetch);

Consideraciones de seguridad

Exponer la información del stack o mensajes de error a usuarios finales puede revelar detalles internos. Buenas prácticas:

  • Loggear el error completo en el servidor y mostrar al usuario un mensaje genérico.
  • Never console.log(error) en producción; usar herramientas como Winston o Bunyan.
  • Sanitizar cualquier dato que provenga del error antes de enviarlo a la UI.

Testing y depuración

Utiliza jest o mocha para validar que los bloques try/catch se comporten como se espera.

test('debe lanzar ValidationError', () => {
  expect(() => validarUsuario({ email: 'bad' }))
    .toThrow(ValidationError);
});

Herramientas de depuración como Chrome DevTools permiten añadir “Break on exceptions” para detener la ejecución justo cuando ocurre el error.

Rendimiento y escalabilidad

El uso indiscriminado de try/catch dentro de bucles de alta frecuencia puede degradar el rendimiento porque el motor debe preparar una tabla de manejo de excepciones. Recomendaciones:

  • Validar condiciones antes de entrar al bloque try siempre que sea posible.
  • En loops críticos (p.ej., procesamiento de streams), mover la captura a nivel superior.
  • Medir con performance.now() o herramientas de profiling antes y después de introducir manejo de errores.

© 2025 BlogTech – Todos los derechos reservados.



Manejo de Errores en JavaScript: Guía Completa de Try / Catch y Buenas Prácticas
ASIMOV Ingeniería S. de R.L. de C.V., Emiliano Nava 15 noviembre, 2025
Compartir
Iniciar sesión dejar un comentario

  
Promesas y async/await en JavaScript: Guía completa y ejemplos prácticos
Aprende en profundidad el funcionamiento de las Promesas y la sintaxis async/await en JavaScript, con ejemplos reales, buenas prácticas, comparativas de rendimiento y consejos de seguridad.