跳至内容
文档
错误处理

错误处理

如果在 fetcher 中抛出错误,它将作为 error 被钩子返回。

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

如果 fetch promise 被拒绝,则会定义 error 对象。

状态码和错误对象

有时我们希望 API 在返回状态码的同时返回错误对象。两者对客户端都有用。

我们可以自定义我们的 fetcher 以返回更多信息。如果状态码不是 2xx,即使它可以解析为 JSON,我们也认为它是错误。

const fetcher = async url => {
  const res = await fetch(url)
 
  // If the status code is not in the range 200-299,
  // we still try to parse and throw it.
  if (!res.ok) {
    const error = new Error('An error occurred while fetching the data.')
    // Attach extra info to the error object.
    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
💡

请注意,dataerror 可以同时存在。因此,UI 可以显示现有数据,同时知道即将到来的请求已失败。

这里 我们有一个示例。

错误重试

SWR 使用 指数退避算法 (在新标签页中打开) 在错误时重试请求。该算法允许应用程序从错误中快速恢复,但不会浪费资源过于频繁地重试。

您也可以通过 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)
  }
})

此回调让您可以根据各种条件进行重试。您还可以通过设置 shouldRetryOnError: false 来禁用它。

也可以通过 全局配置 上下文提供它。

全局错误报告

您始终可以在组件内部以响应式方式获取 error 对象。但是,如果您想全局处理错误,以便通知 UI 显示 Toast (在新标签页中打开)Snackbar (在新标签页中打开),或将其报告到某个地方(例如 Sentry (在新标签页中打开)),有一个 onError 事件。

<SWRConfig value={{
  onError: (error, key) => {
    if (error.status !== 403 && error.status !== 404) {
      // We can send the error to Sentry,
      // or show a notification UI.
    }
  }
}}>
  <MyApp />
</SWRConfig>