コンテンツにスキップ
ドキュメント
エラー処理

エラー処理

fetcher 関数内でエラーがスローされた場合、フックによって error として返されます。

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

フェッチプロミスが拒否された場合、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に トースト (新しいタブで開きます) または スナックバー (新しいタブで開きます) を表示するように通知したり、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>