错误处理
如果在 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
💡
请注意,data
和 error
可以同时存在。因此,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>