跳到內容
文件
錯誤處理

錯誤處理

如果 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
💡

請注意,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>