본문으로 건너뛰기

에러 처리/Toast

이 문서로 해결할 질문

  • API 실패·렌더 예외·404는 각각 어떻게 처리하나요?
  • React Query 전역 오류 Toast를 끄거나 메시지를 바꾸려면 어떻게 하나요?
  • 새 액션 실패 UX를 추가할 때 어디에 코드를 넣나요?

역할 분담

수단사용 시점구현 위치
error.tsx라우트 트리 복구 불가 렌더 예외client/src/.../error.tsx
global-error.tsx루트 layout 포함 치명적 예외client/src/.../global-error.tsx
not-found.tsx404 (리소스 없음)client/src/.../not-found.tsx
인라인 Alert화면 고정 안내 (크레딧 소진 등)해당 페이지 컴포넌트
전역 Toast복구 가능한 API·백그라운드 실패client/src/.../toast/

라우트는 죽이지 않고 컨텍스트를 유지해야 하는 오류는 Toast로 처리합니다.

React Query 전역 오류

QueryClient 생성 시 QueryCache / MutationCacheonError에서 notifyApiError를 호출합니다.

구현은 client/src/.../query-client.provider.tsxclient/src/.../global-query-error-toast.ts에 있습니다.

meta 옵션

개별 useQuery / useMutation에서 전역 Toast를 제어합니다.

meta 필드의미
suppressGlobalErrorToast: true전역 Toast 비활성 (화면에서 직접 처리)
errorToastTitleToast 제목 오버라이드

예: useCurrentUser는 기본 errorToastTitle: '세션을 불러오지 못했어요'를 설정합니다.

타입 확장은 client/src/.../react-query-meta.d.ts에 정의되어 있습니다.

API

함수/훅용도
notifyApiError(error, options?)ApiError → 사용자 메시지 + Toast enqueue
useErrorToast()훅 래퍼 (의존성 배열에 넣기 쉬움)
useToast()enqueue / dismiss / clear 직접 제어

메시지 변환은 client/src/.../error.tsgetUserMessage를 사용합니다.

Toast 옵션 패턴

옵션동작
dedupeKey동일 키 Toast upsert; 2.5초 내 재호출 무시
skipDedupe: true시간 기반 중복 억제 해제
durationMs: 0자동 닫힘 없음
action: { label, onAction }예: 챗봇 "다시 시도"

Provider 순서

Provider 순서는 client/src/.../layout.tsx에서 다음과 같이 유지합니다.

Toast 브리지가 Query 오류 콜백 시점에 등록되도록 이 순서를 유지합니다.

접근성

variantARIA
errorrole="alert", aria-live="assertive"
그 외role="status", aria-live="polite"

새 기능 추가 시 가이드

  1. 백그라운드 fetch 실패는 React Query와 전역 Toast를 기본으로 사용합니다. 화면 인라인 처리가 필요하면 suppressGlobalErrorToast를 설정합니다.
  2. 사용자 액션 실패(저장·삭제)는 useMutation을 사용하고, 필요 시 errorToastTitle을 지정합니다.
  3. 페이지 전체 불가 시 Error Boundary 또는 notFound()를 사용합니다.
  4. 인증 만료http-client 401 refresh 흐름(인증)으로 처리하며, Toast와는 별도입니다.

테스트

pnpm --filter client test:unit

관련 문서