Command Palette

Search for a command to run...

try, catch, finally: Manejo de Errores en JavaScript

Aprende a capturar, manejar y controlar excepciones usando bloques try/catch/finally para escribir código más robusto y predecible.

Lectura: 12 min
Nivel: Principiante

TL;DR - Resumen rápido

  • try/catch captura errores en tiempo de ejecución para que el programa no colapse
  • finally siempre se ejecuta, haya error o no, ideal para limpieza de recursos
  • El objeto error tiene propiedades name, message y stack para depuración
  • Los bloques try-catch pueden anidarse para manejar errores a diferentes niveles
  • No uses try-catch para control de flujo normal, solo para excepciones reales

Introducción al Manejo de Errores

El manejo de errores es una parte fundamental de cualquier aplicación robusta. Sin un control adecuado, un solo error puede hacer que toda tu aplicación colapse dejando una mala experiencia al usuario. JavaScript proporciona el bloquetry/catch/finally como mecanismo principal para capturar y manejar excepciones de forma controlada.

Un buen manejo de errores no solo previene que tu aplicación colapse, sino que también proporciona información útil para debugging, mejora la experiencia del usuario con mensajes claros y permite implementar estrategias de recuperación como valores por defecto o limpieza de recursos. Con try/catch/finally, puedes anticipar posibles fallos, manejarlos elegantemente y mantener tu aplicación funcionando incluso cuando algo sale mal.

  • <strong>try</strong>: Contiene el código que podría lanzar un error
  • <strong>catch</strong>: Se ejecuta si ocurre un error en try, recibe el objeto de error
  • <strong>finally</strong>: Se ejecuta siempre, haya error o no, ideal para limpieza
  • <strong>throw</strong>: Permite lanzar errores personalizados manualmente

Sintaxis Básica de Try-Catch

La sintaxis básica de try/catch/finally es directa pero poderosa. El bloque try contiene el código que podría fallar, el bloque catch maneja cualquier error que ocurra, y el bloquefinally ejecuta código de limpieza independientemente del resultado.

sintaxis-basica.js
Loading code...

En este ejemplo puedes ver cómo funciona el flujo de ejecución. Cuando ocurre un error en el bloque try, el código salta inmediatamente al bloquecatch y luego ejecuta el bloque finally. Si no hay error, el catch se omite pero el finally siempre se ejecuta.

División por cero no es un error en JavaScript

A diferencia de otros lenguajes como Python o Java, dividir por cero en JavaScript no lanza un error. El resultado es Infinity o-Infinity. Los errores reales ocurren con operaciones inválidas como acceder a propiedades de null o parsear JSON inválido.

El Objeto Error

Cuando ocurre un error en el bloque try, JavaScript crea un objeto Error que contiene información valiosa sobre lo que sucedió. Este objeto se pasa automáticamente al bloque catchy tiene tres propiedades principales que te ayudarán a depurar el problema.

objeto-error.js
Loading code...

El objeto Error te da toda la información necesaria para entender qué falló. La propiedad name indica el tipo de error, messagedescribe el problema en lenguaje natural y stack muestra la secuencia de llamadas que llevaron al error, lo cual es invaluable para debugging.

  • <strong>name</strong>: Tipo de error (TypeError, ReferenceError, SyntaxError, etc.)
  • <strong>message</strong>: Descripción legible del error
  • <strong>stack</strong>: Traza de la pila de llamadas que causó el error

El Bloque Finally

El bloque finally es opcional pero extremadamente útil. Se ejecuta siempre, sin importar si el bloque try terminó exitosamente o si lanzó un error. Esto lo hace perfecto para operaciones de limpieza como cerrar conexiones, liberar recursos o limpiar variables temporales.

bloque-finally.js
Loading code...

Este ejemplo muestra cómo finally garantiza que la conexión se cierre correctamente incluso cuando ocurre un error. También demuestra un comportamiento importante: finally se ejecuta antes del return, lo que significa que puede afectar el flujo de salida si modificas variables en él.

Cuidado con return en finally

Si el bloque finally tiene un return, este sobrescribirá cualquier return en try o catch. Esto puede causar comportamientos inesperados y es considerado una mala práctica. Usafinally solo para limpieza, no para modificar el valor de retorno.

Try sin Catch

Aunque es menos común, puedes usar try con finally sin un bloque catch. En este caso, si ocurre un error en el bloquetry, el error se propagará después de que se ejecute finally. Esto es útil cuando quieres asegurar la limpieza de recursos pero no quieres manejar el error en ese punto.

try-solo.js
Loading code...

Este patrón es especialmente útil cuando necesitas liberar recursos pero quieres que el error se propague a un nivel superior donde pueda ser manejado apropiadamente. Por ejemplo, al leer archivos, puedes asegurar que el archivo se cierre incluso si el formato es incorrecto, pero dejar que el error de formato se maneje en otro lugar.

Patrón de limpieza de recursos

Usa try/finally sin catch cuando necesites liberar recursos pero el error debe propagarse. Esto evita duplicar código de limpieza en múltiples bloques catch y mantiene el manejo de errores en el nivel apropiado de la aplicación.

Try-Catch Anidado

Los bloques try/catch pueden anidarse para manejar errores a diferentes niveles de granularidad. Esto es útil cuando una operación tiene múltiples pasos donde cada uno puede fallar de diferentes formas y requiere un manejo específico.

try-anidado.js
Loading code...

Este ejemplo muestra cómo anidar bloques try/catch para manejar diferentes tipos de errores específicamente. El bloque externo maneja errores de tipo de datos, mientras que el bloque interno maneja errores específicos de parsing JSON. Si el JSON es válido pero no tiene la estructura esperada, el error se relanza al bloque externo.

Cuándo anidar try-catch

Anida try/catch cuando necesites manejar errores específicos en sub-operaciones mientras mantienes un manejo general en el nivel superior. Sin embargo, evita anidar excesivamente ya que puede hacer el código difícil de leer. Considera extraer sub-operaciones en funciones separadas.

Errores Comunes

Al trabajar con try/catch/finally, hay varios errores comunes que los desarrolladores cometen, especialmente cuando están aprendiendo. Reconocer estos patrones problemáticos te ayudará a escribir código más robusto y mantenible.

errores-comunes.js
Loading code...

Este ejemplo muestra los errores más frecuentes: bloques catchvacíos que silencian errores sin manejarlos, uso de throw para control de flujo normal, modificaciones de variables en finallyque no afectan el return, y olvidar cerrar recursos en el bloquefinally.

Nunca uses catch vacío

Un bloque catch vacío es una de las peores prácticas en manejo de errores. Silencia errores sin dar ninguna pista de qué salió mal, haciendo debugging casi imposible. Si no puedes manejar el error apropiadamente, relánzalo con throw error o al menos registra el error conconsole.error.

Patrones Útiles

Hay varios patrones comunes que utilizan try/catch/finally para resolver problemas específicos. Dos patrones fundamentales son el uso de valores por defecto cuando falla una operación, y el patrón de reintentos para operaciones que pueden fallar temporalmente.

patron-reintentar.js
Loading code...

El primer patrón muestra cómo proporcionar valores por defecto cuando falla la lectura de datos (como configuraciones del usuario). El segundo patrón implementa reintentos para operaciones que pueden fallar temporalmente, como lecturas de archivos o validaciones. En lugar de fallar inmediatamente, el código reintenta la operación varias veces antes de lanzar el error final.

  • <strong>Valores por defecto</strong>: Usar catch para retornar valores alternativos cuando falla la operación
  • <strong>Reintentos automáticos</strong>: Reintentar operaciones que pueden fallar temporalmente
  • <strong>Limpieza de recursos</strong>: Usar finally para cerrar conexiones/archivos siempre
  • <strong>Validación estructurada</strong>: Lanzar errores descriptivos para validaciones críticas

Resumen: try, catch, finally

Conceptos principales:

  • try/catch captura errores en tiempo de ejecución para evitar colapsos
  • finally siempre se ejecuta, ideal para limpieza de recursos
  • El objeto error tiene name, message y stack para depuración
  • Los bloques pueden anidarse para manejar errores a diferentes niveles
  • try puede usarse solo con finally para limpiar sin manejar el error

Mejores prácticas:

  • Nunca uses catch vacío - siempre maneja o relanza el error
  • Usa finally para cerrar conexiones, archivos y liberar recursos
  • No uses throw para control de flujo normal, solo para excepciones
  • Evita modificar variables en finally que afecten el return
  • Implementa reintentos con backoff para operaciones que pueden fallar temporalmente

Siguiente paso: try/catch con async/await

Este artículo cubre try/catch en código síncrono. Si estás trabajando con operaciones asíncronas (Promesas, async/await, fetch, etc.), consulta el artículo especializado Manejo de Errores con try/catch en async/await en el módulo de asincronía, donde aprenderás sobre unhandled rejections, reintentos para APIs, y patrones específicos de código asíncrono.