Médio JavaScript

Tratamento de erro assíncrono

Enunciado

Crie uma função async chamada dividir que recebe dois números e retorna a divisão do primeiro pelo segundo. Se o segundo número for zero, a função deve lançar um erro com a mensagem Divisão por zero não permitida. Chame a função com (10, 2) e (10, 0), tratando os erros com try/catch e imprimindo o resultado ou a mensagem de erro.

Requisitos

  • A função dividir deve ser async e usar await para simular uma operação assíncrona (ex.: esperar 100ms).
  • Deve lançar um erro quando o divisor for zero.
  • O try/catch deve capturar o erro e imprimir a mensagem.
  • A saída deve mostrar o resultado da divisão válida e a mensagem de erro para a inválida.

Código inicial

// Crie a função async dividir(a, b) que espera 100ms e retorna a/b
// Se b for 0, lance um erro com a mensagem 'Divisão por zero não permitida'
// Chame dividir(10, 2) e dividir(10, 0) com try/catch

Saída esperada

Resultado: 5
Erro: Divisão por zero não permitida
Ver dica

Use throw new Error('mensagem') para lançar o erro. O try/catch deve envolver a chamada com await.

Mostrar solução
// Função auxiliar para simular atraso
function esperar(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// Função assíncrona que divide dois números
async function dividir(a, b) {
  await esperar(100); // simula operação assíncrona
  if (b === 0) {
    throw new Error('Divisão por zero não permitida');
  }
  return a / b;
}

// Função principal para testar
async function main() {
  try {
    const resultado = await dividir(10, 2);
    console.log(`Resultado: ${resultado}`);
  } catch (erro) {
    console.log(`Erro: ${erro.message}`);
  }

  try {
    const resultado = await dividir(10, 0);
    console.log(`Resultado: ${resultado}`);
  } catch (erro) {
    console.log(`Erro: ${erro.message}`);
  }
}

main();

Passo a passo

  1. Definimos esperar para simular uma operação assíncrona de 100ms.
  2. A função dividir é async e usa await esperar(100) para pausar.
  3. Verificamos se b é zero; se for, lançamos um Error com a mensagem especificada.
  4. Caso contrário, retornamos a / b.
  5. Em main, chamamos dividir(10, 2) dentro de um try; se não houver erro, imprimimos o resultado.
  6. No catch, capturamos qualquer erro e imprimimos Erro: ${erro.message}.
  7. Repetimos o processo para dividir(10, 0), que lançará o erro e será capturado.

Por que funciona

O throw dentro de uma função async faz com que a Promise retornada seja rejeitada. O await em uma Promise rejeitada lança uma exceção no ponto da chamada, que pode ser capturada pelo try/catch ao redor. Isso permite tratar erros assíncronos de forma semelhante a erros síncronos.

Erros comuns

  • Não usar await na chamada dentro do try: se você fizer const p = dividir(10,0) sem await, o erro não será capturado pelo try/catch atual, pois a rejeição ocorre depois.
  • Esquecer de lançar o erro com throw: se apenas retornar uma mensagem, o catch não será acionado.
  • Capturar o erro fora da função async: o try/catch deve estar no mesmo escopo async onde o await é usado.

Outra forma de resolver

Usar .catch() na Promise:

dividir(10, 0).catch(erro => console.log(`Erro: ${erro.message}`));

Útil quando não se está dentro de uma função async.

Saída esperada

Resultado: 5
Erro: Divisão por zero não permitida