错误处理
如果在 fetcher
中抛出错误,hook 会将其作为 error
返回。
const fetcher = url => fetch(url).then(r => r.json())// ...const { data, error } = useSWR('/api/user', fetcher)
如果 fetch promise 被拒绝,将定义 error
对象。
Status Code and Error Object(状态码和错误对象)
有时我们希望 API 在返回状态码的同时返回一个错误对象。它们对客户端都是有用的。
我们可以自定义 fetcher
以返回更多信息。如果状态码不是 2xx
,我们则认为它是一个错误,即使它可以被解析为 JSON:
const fetcher = async url => { const res = await fetch(url) // 如果状态码不在 200-299 的范围内, // 我们仍然尝试解析并抛出它。 if (!res.ok) { const error = new Error('An error occurred while fetching the data.') // 将额外的信息附加到错误对象上。 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 可以在知道即将到来的请求失败时显示现有数据。
这里有一个示例。
Error Retry(错误重试)
在出现错误时 SWR 使用指数退避算法重发请求。该算法允许应用从错误中快速恢复,而不会浪费资源频繁地重试。
你还可以通过 onErrorRetry 选项覆盖该行为:
useSWR('/api/user', fetcher, { onErrorRetry: (error, key, config, revalidate, { retryCount }) => { // 404 时不重试。 if (error.status === 404) return // 特定的 key 时不重试。 if (key === '/api/user') return // 最多重试 10 次。 if (retryCount >= 10) return // 5秒后重试。 setTimeout(() => revalidate({ retryCount: retryCount + 1 }), 5000) }})
这个回调让你可以灵活的根据各种条件重试。你也可以通过设置 shouldRetryOnError: false
来禁用它。
也可以通过全局配置 context 来提供它。
Global Error Report(全局错误报告)
你总是可以响应性的在组件内部得到 error
对象。但如果你想要全局处理错误,通知 UI 显示一个 toast 或者一个 snackbar,或在某处报告它,比如 Sentry,可以用 onError
事件:
<SWRConfig value={{ onError: (error, key) => { if (error.status !== 403 && error.status !== 404) { // 我们可以把错误发送给 Sentry, // 或显示一个通知 UI。 } }}}> <MyApp /></SWRConfig>