エラー処理
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
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に トースト (新しいタブで開きます) または スナックバー (新しいタブで開きます) を表示するように通知したり、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>