CAP 07 · LEC 01·Manejo de errores

try / catch / finally: maneja errores sin romper la app

El código falla — siempre. try/catch/finally te da un lugar donde capturar esos fallos y decidir qué hacer, sin que toda la aplicación se detenga.

● PRINCIPIANTE7 min lectura4 ejerciciospor Fernando Herrera · actualizado mayo de 2026
¿Encontraste un error o algo que mejorar?Editá esta lección en GitHub →

¿Por qué manejar errores?

Cuando JavaScript encuentra un error que no está manejado, detiene la ejecución del programa. En el navegador eso puede congelar la interfaz; en Node.js puede tumbar el servidor. El manejo de errores es lo que separa el código de producción del código de prototipo.

// Sin manejo: el programa se detiene en la línea del error const texto = null; console.log(texto.toUpperCase()); // TypeError — crash console.log("Esta línea nunca se ejecuta");
// Sin manejo: el programa se detiene en la línea del error const texto: string | null = null; console.log(texto!.toUpperCase()); // TypeError — crash console.log("Esta línea nunca se ejecuta");
SalidaTypeError: Cannot read properties of null (reading 'toUpperCase')
Errores en tiempo de ejecución

TypeScript puede atrapar muchos errores en tiempo de compilación, pero errores como respuestas de red fallidas, archivos que no existen o datos inesperados de una API solo aparecen cuando el código se ejecuta.

try / catch — captura errores sin romper la app

Envuelves el código peligroso en un bloque try. Si algo falla, el control pasa inmediatamente al bloque catch. El resto del programa continúa normalmente.

function parsearJSON(texto) { try { const datos = JSON.parse(texto); return datos; } catch (error) { console.error("JSON inválido:", error.message); return null; } } console.log(parsearJSON('{"nombre": "Ana"}')); // { nombre: "Ana" } console.log(parsearJSON("esto no es json")); // null console.log("El programa sigue ejecutándose"); // se ejecuta siempre
function parsearJSON<T>(texto: string): T | null { try { const datos = JSON.parse(texto) as T; return datos; } catch (error) { if (error instanceof Error) { console.error("JSON inválido:", error.message); } return null; } } interface Usuario { nombre: string; } console.log(parsearJSON<Usuario>('{"nombre": "Ana"}')); // { nombre: "Ana" } console.log(parsearJSON<Usuario>("esto no es json")); // null console.log("El programa sigue ejecutándose");
Salida{ nombre: "Ana" } null El programa sigue ejecutándose
No silencies errores sin razón

Un catch vacío que no hace nada es peor que no tener catch. Al menos registra el error con console.error para poder diagnosticarlo después.

finally — código que se ejecuta siempre

El bloque finally se ejecuta sin importar si hubo error o no. Es el lugar correcto para liberar recursos: cerrar conexiones, ocultar spinners de carga, limpiar temporizadores.

function obtenerDatos(url) { let cargando = true; console.log("Iniciando carga..."); try { // Simulamos una operación que puede fallar if (!url.startsWith("https")) { throw new Error("Solo se permiten URLs seguras"); } console.log("Datos obtenidos de:", url); return { ok: true }; } catch (error) { console.error("Error:", error.message); return null; } finally { // Esto se ejecuta SIEMPRE — con éxito o con error cargando = false; console.log("Carga terminada. cargando =", cargando); } } obtenerDatos("https://api.ejemplo.com/datos"); console.log("---"); obtenerDatos("http://inseguro.com");
interface Respuesta { ok: boolean; } function obtenerDatos(url: string): Respuesta | null { let cargando = true; console.log("Iniciando carga..."); try { if (!url.startsWith("https")) { throw new Error("Solo se permiten URLs seguras"); } console.log("Datos obtenidos de:", url); return { ok: true }; } catch (error) { if (error instanceof Error) { console.error("Error:", error.message); } return null; } finally { cargando = false; console.log("Carga terminada. cargando =", cargando); } } obtenerDatos("https://api.ejemplo.com/datos"); console.log("---"); obtenerDatos("http://inseguro.com");
SalidaIniciando carga... Datos obtenidos de: https://api.ejemplo.com/datos Carga terminada. cargando = false --- Iniciando carga... Error: Solo se permiten URLs seguras Carga terminada. cargando = false

El objeto error en catch

El valor capturado por catch tiene tres propiedades clave que te dan contexto sobre qué salió mal.

try { // Forzamos un ReferenceError console.log(variableQueNoExiste); } catch (error) { console.log("Tipo:", error.name); // "ReferenceError" console.log("Mensaje:", error.message); // "variableQueNoExiste is not defined" console.log("Stack:", error.stack); // traza completa de llamadas } // Inspeccionando errores propios try { throw new TypeError("Se esperaba un número"); } catch (error) { console.log(error.name); // "TypeError" console.log(error.message); // "Se esperaba un número" }
// En TypeScript, el tipo de 'error' en catch es 'unknown' // Debes verificar antes de acceder a sus propiedades try { const valor: unknown = null; (valor as any).propiedad; // forzamos un error } catch (error) { if (error instanceof Error) { // Dentro de este bloque, TypeScript sabe que es Error console.log("Tipo:", error.name); console.log("Mensaje:", error.message); console.log("Stack:", error.stack?.split(" ")[0]); // primera línea } else { console.log("Error desconocido:", error); } }
SalidaTipo: ReferenceError Mensaje: variableQueNoExiste is not defined
TypeScript: error es unknown

En TypeScript, el parámetro del catch tiene tipo unknown (no Error). Siempre verifica con instanceof Error antes de acceder a error.message o error.name. Esto previene accesos inseguros a propiedades.

Practica