追記: 2021年6月8日
SWR公式日本語訳ページが追加されたので、そちらをご覧ください
このページは Error Handling – SWRの日本語訳です
SWR日本語訳全体についてはSWR 日本語訳をご覧ください
エラーハンドリング
fetcher
内でエラーがスローされた場合、フックによってerror
として返されます。
const fetcher = url => fetch(url).then(r => r.json())
// ...
const { data, error } = useSWR('/api/user', fetcher)
fetch promise が reject された場合にerror
オブジェクトが定義されます。
ステータスコードとエラーオブジェクト
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は次のリクエストが失敗したことを認識しながら、既存のデータを表示できます。
ここに例があります
エラーでの再試行
SWRは、指数バックオフアルゴリズム(exponential backoff algorithm)を使用して、エラー時に要求を再試行します。 このアルゴリズムにより、アプリはエラーからすばやく回復できますが、リソースを無駄に再試行することはありません。
onErrorRetryオプションを使用して、この動作をオーバーライドすることもできます。
useSWR('/api/user', fetcher, {
onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
// 404はリトライしません
if (error.status === 404) return
// 特定のキーはリトライしません
if (key === '/api/user') return
// 10回だけリトライします
if (retryCount >= 10) return
// 5秒後にリトライします
setTimeout(() => revalidate({ retryCount: retryCount + 1 }), 5000)
}
})
このコールバックにより、さまざまな条件に基づいて再試行できる柔軟性が得られます。 shouldRetryOnError:false
を設定して無効にすることもできます。
これらは グローバル設定 Context を介して設定することもできます。
グローバルエラーレポート
コンポーネント内の error
オブジェクトはいつでもリアクティブに取得できます。 ただし、エラーをグローバルで処理する場合、toast や snackbar を表示するようにUIに通知する場合、またはSentryなどの場所で報告する場合は、onError
イベントがあります。
<SWRConfig value={{
onError: (error, key) => {
if (error.status !== 403 && error.status !== 404) {
// Sentry にエラーを送信します
// または、通知UIを表示します
}
}
}}>
<MyApp />
</SWRConfig>