DevPath · Aprende a programar ESPTEN

Asincronía: promesas y async/await

Errores asíncronos

El error que "vuela" en otro momento

Manejar errores en código asíncrono es distinto porque el fallo no ocurre en la línea donde escribiste la llamada, sino más tarde, cuando la promesa se resuelve. Hay dos herramientas principales.

1. try/catch con await

Dentro de una función async, await convierte un rechazo en una excepción que puedes atrapar con try...catch normal, como si fuera código síncrono:

async function cargar() {
  try {
    const datos = await pedirDatos(); // si se rechaza, salta al catch
    return datos;
  } catch (error) {
    console.log("Falló:", error.message);
    return null; // valor por defecto
  }
}

2. .catch() encadenado

Sin async/await, se usa .catch() al final de la cadena:

pedirDatos()
  .then((datos) => usar(datos))
  .catch((error) => console.log("Falló:", error.message));

El error clásico: try/catch SIN await

Esto NO funciona como esperas:

async function malo() {
  try {
    pedirDatos(); // ¡falta el await!
  } catch (error) {
    console.log("Esto nunca se ejecuta");
  }
}

Sin await, la línea pedirDatos() solo crea la promesa y sigue adelante; el try ya terminó cuando, mucho después, la promesa se rechaza. El catch síncrono no puede atrapar un fallo que ocurre fuera de su tiempo de vida. Es como cerrar la red de seguridad antes de que el trapecista salte.

Regla: un try/catch solo atrapa el rechazo de una promesa si pones await delante (o si devuelves la promesa y manejas el error con .catch).

Rechazos no capturados

Si una promesa se rechaza y nadie la maneja (ni await en un try, ni un .catch), se produce un unhandled rejection. En el navegador verás un warning en consola; en Node, por defecto, termina el proceso. Por eso toda promesa que pueda fallar debería tener su manejador de error.

// ❌ Rechazo sin manejar: warning / proceso caído
Promise.reject(new Error("nadie me atrapa"));

// ✅ Manejado
Promise.reject(new Error("ya me atrapan")).catch((e) => console.log(e.message));

Ejemplos

try/catch con await devuelve un valor por defecto

function fallar() {
  return Promise.reject(new Error("boom"));
}
async function seguro() {
  try {
    return await fallar();
  } catch (e) {
    return "valor por defecto";
  }
}
seguro().then((v) => console.log(v)); // "valor por defecto"

Sin await, el catch NO atrapa el rechazo

function fallar() {
  return Promise.reject(new Error("boom"));
}
async function malo() {
  try {
    const p = fallar(); // sin await
    p.catch(() => {}); // lo silenciamos para no romper la demo
    return "el try terminó sin atrapar nada";
  } catch (e) {
    return "esto NO se ejecuta";
  }
}
malo().then((v) => console.log(v));
Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
← Combinadores de promesasVer el módulo →