DevPath · Aprenda a programar ESPTEN

Assincronia: promessas e async/await

Erros assíncronos

O erro que "voa" em outro momento

Tratar erros em código assíncrono é diferente porque a falha não ocorre na linha onde você escreveu a chamada, mas mais tarde, quando a promessa é resolvida. Há duas ferramentas principais.

1. try/catch com await

Dentro de uma função async, await transforma uma rejeição em uma exceção que você pode capturar com um try...catch normal, como se fosse código síncrono:

async function carregar() {
  try {
    const dados = await pedirDados(); // se for rejeitada, pula para o catch
    return dados;
  } catch (erro) {
    console.log("Falhou:", erro.message);
    return null; // valor padrão
  }
}

2. .catch() encadeado

Sem async/await, usa-se .catch() no final da cadeia:

pedirDados()
  .then((dados) => usar(dados))
  .catch((erro) => console.log("Falhou:", erro.message));

O erro clássico: try/catch SEM await

Isto NÃO funciona como você espera:

async function ruim() {
  try {
    pedirDados(); // faltou o await!
  } catch (erro) {
    console.log("Isto nunca é executado");
  }
}

Sem await, a linha pedirDados() apenas cria a promessa e segue adiante; o try já terminou quando, muito depois, a promessa é rejeitada. O catch síncrono não consegue capturar uma falha que ocorre fora do seu tempo de vida. É como fechar a rede de segurança antes de o trapezista saltar.

Regra: um try/catch só captura a rejeição de uma promessa se você colocar await na frente (ou se devolver a promessa e tratar o erro com .catch).

Rejeições não capturadas

Se uma promessa é rejeitada e ninguém a trata (nem await em um try, nem um .catch), ocorre um unhandled rejection. No navegador você verá um warning no console; no Node, por padrão, encerra o processo. Por isso toda promessa que possa falhar deveria ter o seu tratador de erro.

// ❌ Rejeição sem tratamento: warning / processo derrubado
Promise.reject(new Error("ninguém me captura"));

// ✅ Tratada
Promise.reject(new Error("agora me capturam")).catch((e) => console.log(e.message));

Exemplos

try/catch com await devolve um valor padrão

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

Sem await, o catch NÃO captura a rejeição

function falhar() {
  return Promise.reject(new Error("boom"));
}
async function ruim() {
  try {
    const p = falhar(); // sem await
    p.catch(() => {}); // silenciamos para não quebrar a demo
    return "o try terminou sem capturar nada";
  } catch (e) {
    return "isto NÃO é executado";
  }
}
ruim().then((v) => console.log(v));
Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
← Combinadores de promessasVer o módulo →