Skip to content
Docs
Gestión De Errores

Gestión De Errores

Si se lanza un error dentro del fetcher, será devuelto como error por el hook.

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

El objeto error será definido si la promise de fetch es rechazada.

Código de estado y objeto de error

A veces queremos que una API devuelva un objeto de error junto con el status code. Ambos son útiles para el cliente.

Podemos personanilizar nuestro fetcher para que devuelve más información. Si el status code no es 2xx, lo consideramos un error aunque se pueda analizar como JSON:

const fetcher = async url => {
  const res = await fetch(url)
 
  // Si el status code no esta en el rango 200-299,
  // seguimos intentando analizarlo y lanzarlo.
  if (!res.ok) {
    const error = new Error('An error occurred while fetching the data.')
    // Adjunta información extra al objeto de error.
    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
 
💡

Tenga en cuenta que data y error pueden existir al mismo tiempo. Por lo tanto la UI puede mostrar data existente, mientras se sabe que la próxima solicitud ha fallado.

Aquí tenemos un ejemplo.

Reintento de error

SWR utiliza el exponential backoff algorithm (opens in a new tab) para reintentar la solicitud en el error. El algoritmo permite que la aplicación se recupere de los errores rápidamente, pero si malgastar recursos reintentando con demasiada frecuencia.

También podemos anular este comportamiento mediante la opción onErrorRetry:

useSWR('/api/user', fetcher, {
  onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
    // Never retry on 404.
    if (error.status === 404) return
 
    // Never retry for a specific key.
    if (key === '/api/user') return
 
    // Only retry up to 10 times.
    if (retryCount >= 10) return
 
    // Retry after 5 seconds.
    setTimeout(() => revalidate({ retryCount }), 5000)
  }
})

Este callback le da flexibilidad de reintentar basado en varias condiciones. También puede desactivar estableciendo shouldRetryOnError: false.

También es posible propocionar a través del Global Configuration context.

Informe global de errores

Siempre puedes obtener el objeto de error dentro del componente de forma reactiva. Pero en caso de que quieras manejar el error de forma global, para notificar a la UI que muestre un toast (opens in a new tab) o un snackbar (opens in a new tab), o reportarlo en algún lugar como Sentry (opens in a new tab), hay un evento onError:

<SWRConfig value={{
  onError: (error, key) => {
    if (error.status !== 403 && error.status !== 404) {
      // Podemos enviar el error a Sentry
      // o mostrarlo una notificación UI.
    }
  }
}}>
  <MyApp />
</SWRConfig>