Skip to content
문서
에러 처리

에러 처리

fetcher 안에서 에러가 발생했다면 hook에 의해 error로 반환됩니다.

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

fetch 프로미스가 거부되면 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
💡

데이터에러는 동시에 존재할 수 있습니다. 따라서 UI는 예정된 요청이 실패했음을 알면서도 기존 데이터를 보여줄 수 있습니다.

여기에 예시가 있습니다.

에러 재시도

SWR은 지수 백오프 알고리즘 (opens in a new tab)를 사용해 에러 시 요청을 재시도합니다. 이 알고리즘을 사용하면 에러로부터 앱을 빠르게 복구할 수 있으며 너무 자주 재시도하여 리소스를 낭비하지도 않습니다.

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 }), 5000)
  }
})

이 콜백을 사용하면 다양한 조건을 기반으로 유연하게 재시도할 수 있습니다. shouldRetryOnError: false 설정으로 비활성화할 수도 있습니다.

전역 설정 컨텍스트를 통해 제공하는 것도 가능합니다.

전역 에러 기록

항상 컴포넌트 내에서 반응적으로 error 객체를 얻을 수 있습니다. 하지만 UI에 토스트 (opens in a new tab) 또는 스낵바 (opens in a new tab)를 보여주거나 Sentry (opens in a new tab)와 같은 어딘가에 기록하기 위해 에러를 전역으로 처리하길 원할 경우, onError 이벤트가 있습니다.

<SWRConfig value={{
  onError: (error, key) => {
    if (error.status !== 403 && error.status !== 404) {
      // Sentry로 에러를 보내거나,
      // 알림 UI를 보여줄 수 있습니다.
    }
  }
}}>
  <MyApp />
</SWRConfig>