Skip to content
Documentação
Manipulação de Erros

Manipulação de Erros

Se um erro é lançado dentro de fetcher, ele será retornado como error pelo hook.

const fetcher = url => fetch(url).then(r => r.json())
 
// ...
const { data, error } = useSWR('/api/user', fetcher)

O objeto error será definido se a fetch promise for rejeitada.

Código de Status e Objeto de Erro

As vezes queremos uma API para retornar um objeto de erro junto ao código de status. Ambos são úteis para o cliente.

Nós podemos customizar nossa função fetcher para retornar mais informações. Se o código de status não for 2xx, consideramos que é um erro mesmo se ele puder ser lido como JSON:

const fetcher = async url => {
  const res = await fetch(url)
 
  // Se o código de status não estiver no raio 200-299,
  // nós ainda tentamos ler o JSON e retornar o objeto de erro
  if (!res.ok) {
    const error = new Error('An error occurred while fetching the data.')
    // Adicionar informação extra ao objeto de erro.
    error.info = await res.json()
    error.status = res.status
    throw error
  }
 
  return res.json()
}
 
// ...
const { data, error } = useSWR('/api/user', fetcher)
// error.info === {
//   message: "You are not authorized to access this resource.",
//   documentation_url: "..."
// }
// error.status === 403
💡

Note que data e error podem existir ao mesmo tempo. Então a UI pode mostrar os dados existentes, enquanto sabe que o próximo pedido falhou.

Aqui nós temos um exemplo.

Retentativas

SWR usa o algoritmo de retentativa exponencial (em inglês) (opens in a new tab) para tentar novamente a requisição em caso de erro. O algoritmo permite a aplicação se recuperar rapidamente de erros, mas não gasta muitos recursos tentando novamente muito frequentemente.

Você também pode sobrescrever este comportamento através da opção onErrorRetry:

useSWR('/api/user', fetcher, {
  onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
    // Nunca tentar ao 404.
    if (error.status === 404) return
 
    // Nunca tentar para uma chave específica
    if (key === '/api/user') return
 
    // Tentar até 10 vezes.
    if (retryCount >= 10) return
 
    // Tentar novamente depois de 5 segundos
    setTimeout(() => revalidate({ retryCount }), 5000)
  }
})

Esse callback dá a você a flexibilidade de tentar novamente baseado em várias condições. Você também pode desativá-lo definindo shouldRetryOnError: false.

Também é possível provê-lo via contexto de Configuração Global.

Relatório de Erros Globais

Você pode sempre obter o objeto de erro dentro do componente reativamente. Mas, no caso de você querer lidar com o erro globalmente, para notificar a UI para mostrar um toast (opens in a new tab) ou snackbar (opens in a new tab), ou reportá-lo em algum lugar como Sentry (opens in a new tab), há um evento chamado onError:

<SWRConfig value={{
  onError: (error, key) => {
    if (error.status !== 403 && error.status !== 404) {
      // Nós podemos enviar o erro para Sentry,
      // ou mostrar uma notificação na interface.
    }
  }
}}>
  <MyApp />
</SWRConfig>