Tratamento de erros em requisições: o que fazer se algo der errado?

Descubra como lidar com falhas ao tentar buscar dados de uma API.

Quando buscamos dados de uma API, nem sempre tudo funciona de primeira.
Pode cair a internet, a API pode responder com erro, ou o dado pode vir em formato inesperado.

Tratar erros é como ter um “plano B”:
se algo falhar, sua aplicação continua organizada e o usuário recebe uma mensagem clara.


tipos comuns de erro em requisições

1) erro de rede

Acontece quando não foi possível completar a requisição (sem internet, servidor fora, bloqueio de rede).

2) erro HTTP

A requisição chegou ao servidor, mas ele respondeu com status de erro, por exemplo:

  • 404 (não encontrado)
  • 500 (erro interno do servidor)
  • 401 (não autorizado)

3) erro ao processar resposta

A resposta veio, mas ao converter (response.json()), pode falhar se o conteúdo estiver inválido.


ponto importante sobre fetch

fetch não lança erro automaticamente só porque veio 404 ou 500.
Por isso, você deve checar response.ok.


exemplo completo com try...catch

async function buscarUsuarios() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users");

    // valida erro HTTP
    if (!response.ok) {
      throw new Error("erro HTTP: " + response.status);
    }

    // tenta converter resposta
    const dados = await response.json();

    console.log("usuários carregados:", dados);
  } catch (erro) {
    console.log("falha na requisição:", erro.message);
  } finally {
    console.log("requisição finalizada");
  }
}

buscarUsuarios();

dando feedback para o usuário

Além de tratar no console, mostre mensagens na tela:

  • “carregando dados...”
  • “não foi possível carregar, tente novamente”
  • “dados carregados com sucesso”

Isso melhora muito a experiência.

Exemplo simples:

const status = document.getElementById("status");

async function carregar() {
  status.textContent = "carregando...";

  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts");

    if (!response.ok) {
      throw new Error("status " + response.status);
    }

    const posts = await response.json();
    status.textContent = "carregado com sucesso! total: " + posts.length;
  } catch (erro) {
    status.textContent = "erro ao carregar dados. tente novamente.";
  }
}

timeout com AbortController (extra útil)

Às vezes a requisição demora demais. Você pode cancelar:

async function buscarComTimeout() {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 5000);

  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos", {
      signal: controller.signal
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
      throw new Error("erro HTTP: " + response.status);
    }

    const dados = await response.json();
    console.log(dados);
  } catch (erro) {
    if (erro.name === "AbortError") {
      console.log("tempo limite excedido");
    } else {
      console.log("erro:", erro.message);
    }
  }
}

boas práticas

  • sempre use try...catch (ou .catch()).
  • sempre valide response.ok.
  • mostre feedback amigável para o usuário.
  • registre erros para debug (console, monitoramento etc.).
  • diferencie tipos de erro quando possível (rede, HTTP, parsing, timeout).

resumo da lição

  • erros em requisição são normais e esperados.
  • fetch precisa de validação manual com response.ok para status HTTP.
  • try...catch...finally organiza bem o fluxo.
  • tratar erro corretamente deixa seu app mais confiável e profissional.