錯誤處理
如果 fetcher
內部拋出錯誤,則 hook 會將其作為 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>