Erros assíncronos
Um try/catch comum não pega sozinho um erro que acontece dentro de uma Promise solta por aí. Só o await dentro de um try/catch, ou o .catch() explícito da Promise, cerca esse tipo de erro de verdade.
Estudar esta lição interativa →No Módulo 8, você aprendeu que await pausa uma função async até uma tarefa demorada terminar. E se essa tarefa falhar, em vez de terminar bem? A boa notícia é que o padrão que você já usou no fetch (envolver o await num try/catch) continua funcionando exatamente como esperado: quando uma Promise é rejeitada (o nome técnico para "essa tarefa assíncrona deu errado"), o await a transforma num erro lançado ali mesmo, e o catch ao redor o pega, igualzinho a um erro síncrono comum.
function buscarUsuario(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id <= 0) reject(new Error("id inválido"));
else resolve({ id, nome: "Usuário " + id });
}, 10);
});
}
async function carregarPerfil(id) {
try {
const usuario = await buscarUsuario(id); // await + try/catch cerca o erro
console.log("Carregado:", usuario.nome);
} catch (erro) {
console.log("Falhou:", erro.message);
}
}
carregarPerfil(1); // Carregado: Usuário 1
carregarPerfil(-1); // Falhou: id inválidoExiste também um jeito de tratar o erro sem async/await, direto na Promise, encadeando um .catch() depois do .then() (ou sozinho). Os dois estilos resolvem o mesmo problema; hoje em dia, async/await com try/catch costuma ser preferido por deixar o código com aparência mais linear e fácil de ler, mas reconhecer o .catch() é importante porque ele aparece bastante em código já existente por aí.
Um erro sutil: envolver a chamada de uma função async num try/catch, mas esquecer o await na frente dela. Sem await, a função assíncrona começa a rodar, mas o código não espera por ela, então, se ela falhar mais tarde, esse erro acontece depois que o bloco try já foi embora, e o catch nunca chega a vê-lo. O resultado costuma ser um aviso de "Uncaught (in promise)" no console, silencioso e fácil de passar batido. Regra de ouro: toda chamada a uma função async dentro de um try que você quer proteger precisa do await na frente.
Esse cuidado importa especialmente ao buscar dados de verdade: uma API pode estar fora do ar, a internet do usuário pode cair no meio do caminho, o servidor pode devolver algo inesperado. Um app que trata esses casos mostra uma mensagem amigável ("Não foi possível carregar, tente novamente"); um que não trata trava a tela ou, pior, mostra um erro técnico cru para quem só queria ver os dados.
// Sua vez! Complete carregarPerfil usando await dentro de um try/catch.
function buscarUsuario(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id <= 0) reject(new Error("id inválido"));
else resolve({ id, nome: "Usuário " + id });
}, 10);
});
}
async function carregarPerfil(id) {
// use await buscarUsuario(id) dentro de um try/catch
// se der certo, retorne o resultado
// se falhar, retorne "Erro ao carregar: " + erro.message
}
carregarPerfil(1).then((r) => console.log(r));
carregarPerfil(-1).then((r) => console.log(r));Complete o tratamento de erro assíncrono e clique em Rodar.