Skip to content

[FIX] 조회 실패 화면이 기본 재시도(3회·지수 백오프) 때문에 약 7초 늦게 뜨는 문제 (#238) - #239

Merged
SinYusi merged 2 commits into
mainfrom
fix/238-query-retry-policy
Oct 12, 2026
Merged

SinYusi merged 2 commits into
mainfrom
fix/238-query-retry-policy

Conversation

@SinYusi

@SinYusi SinYusi commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

closes #238

변경 사항

  • QueryProvider 조회 기본값에 retry 추가
    • ApiError의 4xx(400·401·404 등): 재시도하지 않음 — 다시 보내도 같음. 401은 lib/api.ts가 이미 토큰 재발급·1회 재시도를 마친 결과
    • 그 밖(5xx, 네트워크 오류 NETWORK_ERROR 상태 0, ApiError가 아닌 오류): 1회만 재시도(기본 지연 1초)
  • 대상: 기본값을 쓰는 회원 정보·승차권 목록·영수증·예약 목록·달력 조회. 열차 조회(retry: false)와 mutation(원래 재시도 없음)은 그대로

리뷰어 참고 사항

  • 실패 화면에는 이미 "다시 시도" 버튼이 있어, 재시도를 줄여도 사용자가 다시 조회할 수 있습니다
  • 요청 취소(조건 변경·화면 이탈)는 React Query가 재시도하지 않으므로 이 정책과 무관합니다

추가 정보

실패 확정까지 걸린 시간 (jsdom, 실제 타이머, QueryProvider 그대로 · 요청 시간 0 — 정책 지연만)

오류 main 호출 수 / 시간 head 호출 수 / 시간
500 4 / 7,036 ms 2 / 1,032 ms
네트워크(상태 0) 4 / 7,028 ms 2 / 1,007 ms
401 4 / 7,029 ms 1 / 24 ms
404 4 / 7,018 ms 1 / 25 ms

실제 화면에서는 여기에 요청마다 응답 시간이 더해집니다(main은 4번, head는 1~2번).

검증

  • pnpm exec tsc --noEmit 통과 · pnpm test 334개 통과 · pnpm build 통과
  • 새 테스트 6개(400·401·404 → 1회 / 500·네트워크·비 ApiError → 2회) — 수정 전 코드에서 모두 실패 확인

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 버그 수정
    • 조회 오류 발생 시 오류 유형에 따라 재시도 횟수를 조정했습니다. 400번대 오류는 재시도하지 않고, 서버 오류 등은 한 번 재시도합니다.

@vercel

vercel Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
raillo-frontend Ready Ready Preview Oct 12, 2026 4:16am UTC

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: penggu-dev/raillo-frontend/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 671a19e0-3d95-45da-a1ca-67eef16323a3

📥 Commits

Reviewing files that changed from the base of the PR and between 565a74e and 7c6f17f.


📒 Files selected for processing (2)
  • components/providers/QueryProvider.test.tsx
  • components/providers/QueryProvider.tsx

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



Walkthrough

전역 쿼리에 재시도 규칙을 적용했습니다. 4xx ApiError는 재시도하지 않고, 그 외 오류는 한 번 재시도합니다. 테스트는 오류 유형별 조회 호출 횟수를 검증합니다.

Changes

전역 쿼리 재시도

Layer / File(s) Summary
재시도 규칙 적용 및 검증
components/providers/QueryProvider.tsx, components/providers/QueryProvider.test.tsx
4xx ApiError는 재시도하지 않습니다. 그 밖의 오류는 실패 횟수가 1 미만일 때 재시도합니다. 테스트는 400·401·404 오류의 1회 호출과 500·상태 코드 0·일반 Error의 2회 호출을 확인합니다.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk | ⚪ Minimal · up to 7c6f1

Merge Risk: ⚪ Minimal · up to 7c6f1

Failed lookups will give up faster for client errors and retry once for server and network errors, as intended. No merge-blocking risk was found.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to 7c6f1

Automatic retries are reduced without changing request permissions, credential handling, or authentication refresh controls. No security issue introduced or materially worsened by this change was identified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed reach is client queries using the provider's defaults. The reviewed change reduces repetition of existing operations rather than adding a public request route, credential authority, or privileged sink. The test-file entrypoint signal represents test-only execution.

Trust Boundaries and Controls

  • observed — HTTP status affects whether an existing query repeats; it does not grant access or modify credentials. The retry predicate performs no authentication-store mutation, and refresh-failure cleanup occurs before its decision.

Resilience and Maintainability Implications

  • observed — The API layer rethrows AbortError unchanged, while the new retry predicate has no explicit cancellation branch. Cancellation therefore remains dependent on framework enforcement; the available source does not establish every default-query cancellation path.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description check Passed 설명이 템플릿의 모든 섹션을 포함합니다. 변경 내용, 적용 범위, 검증 결과, 성능 개선 수치를 구체적으로 설명합니다.
Title check Passed 제목이 조회 실패 화면의 지연 원인과 수정 목적을 명확하게 설명하며, 변경 내용과 직접 관련됩니다.
Linked Issues check Passed 직접 연결된 #238의 요구를 충족합니다. QueryProvider.tsx의 전역 queries.retry는 ApiError 상태 400 이상 500 미만을 즉시 실패 처리하고, 그 밖의 오류는 failureCount < 1일 때만 1회 재시도합니다. 따라서 4xx는 0회, 네트워크 오류·5xx·일반 오류는 1회 재시도합니다. `QueryPr…
Out of Scope Changes check Passed 변경 파일은 components/providers/QueryProvider.tsx의 전역 조회 재시도 정책과 이를 검증하는 QueryProvider.test.tsx입니다. 테스트 추가는 #238 구현을 검증하는 지원 변경입니다. 요약과 확인된 파일에서 회원 정보·승차권·영수증·예약·달력 조회 외의 기능 변경이나 mutation 변경은 확인되지 않습니…

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SinYusi
SinYusi merged commit 3388b99 into main Oct 12, 2026
4 checks passed
@SinYusi
SinYusi deleted the fix/238-query-retry-policy branch October 12, 2026 15:58

This branch was successfully deployed

1 active deployment
Preview — 7c6f17f3 Deployed Oct 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 조회 실패 화면이 기본 재시도(3회·지수 백오프) 때문에 약 7초 늦게 뜨는 문제

1 participant