Skip to content

refactor: 에러 문구를 서버 detail 기반으로 통일 + 이미지 5MB 사전검증#320

Merged
ychany merged 4 commits into
devfrom
refactor/305-error-message-policy
Jul 14, 2026
Merged

refactor: 에러 문구를 서버 detail 기반으로 통일 + 이미지 5MB 사전검증#320
ychany merged 4 commits into
devfrom
refactor/305-error-message-policy

Conversation

@ychany

@ychany ychany commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

작업 요약

  • 4xx 에러 토스트 문구를 서버 detail 기반으로 통일합니다 (에러 메시지 정책 status 뭉뚱그림 개선 + 413 사전검증 #305)
  • 공통 에러 메시지 유틸 getApiErrorMessage 를 도입합니다
  • 이미지 업로드에 5MB 사전 용량검증을 추가해 서버 413 왕복을 방지합니다

작업 세부 내용

1. getApiErrorMessage 유틸 도입 — src/utils/getApiErrorMessage.ts

이슈에서 합의된 정책을 코드로 반영:

  • 4xx: 서버 detail 을 그대로 노출 — 문구의 SSOT 는 서버 (프론트 code 매핑 X)
  • 5xx / 네트워크 오류: detail 이 사용자용 문구가 아니므로 fallback 사용
  • fallback 은 호출부에서 컨텍스트에 맞는 문구 전달 가능 (예: '마감 시각을 변경하지 못했어요.')

2. 하드코딩 고정 문구 → detail 교체 (4곳)

위치 Before After
usePostTournamentItemsByWish '위시템 추가에 실패했어요...' 고정 getApiErrorMessage(error, ...)
InviteFriendsDialog 마감 수정 '마감 시각을 변경하지 못했어요.' 고정 getApiErrorMessage(error, ...)
PlateShareDialog 플레이 링크 생성 '공유 링크를 생성하지 못했어요...' 고정 getApiErrorMessage(error, ...)
useDeleteMe 회원 탈퇴 '잠시 후 다시 시도해주세요.' 고정 getApiErrorMessage(error, ...)

이제 만료/권한/중복 등 원인이 다른 실패에 서버가 내려주는 구체적 문구가 그대로 노출됩니다.

참고: usePostTournamentItemsByWish 의 onError 삭제 (전역 안전망 위임) 옵션은 선행 이슈 #299 가 아직 미구현이라 보류 — 삭제 시 silent failure 가 되므로 #299 머지 후 후속 처리.

3. usePatchMe 견고화

기존엔 axios 에러가 아니거나 response 가 없으면 (네트워크 오류) 토스트 없이 조용히 실패 → getApiErrorMessage 로 교체해 항상 사용자 피드백이 보장됩니다.

4. 이미지 업로드 5MB 사전검증 — useImagePicker 공통 적용

  • handleImagesSelect 공통 경로에서 5MB 초과 파일을 업로드 전에 필터 + 안내 토스트
  • 웹 input / 웹뷰 네이티브 피커 두 경로 모두 커버
  • 프로필 이미지·위시 OCR·아이템 이미지 등 4개 사용처 전부 자동 적용 (호출부 수정 0)
  • 기존 skippedCount 는 "지원하지 않는 형식" 의미라 합치지 않고 별도 토스트로 분리

연관 이슈

closes #305

Summary by CodeRabbit

  • 개선 사항
    • 프로필 수정, 회원 탈퇴, 대회 생성·수정 및 공유 기능에서 API 오류 원인을 반영한 안내 메시지를 표시합니다.
    • 이미지 선택 시 5MB를 초과하는 파일을 업로드 전에 자동 제외하고, 초과 파일이 있으면 안내 토스트를 표시합니다.
    • 유효한 이미지만 다음 업로드 단계로 전달해 불필요한 업로드 실패를 줄였습니다.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
depromeet Ready Ready Preview, Comment Jul 14, 2026 3:31pm

@github-actions github-actions Bot added the refactor Extra attention is needed label Jul 9, 2026
@github-actions
github-actions Bot requested review from iOdiO89 and soyeong0115 July 9, 2026 14:26
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1f8b047f-411b-4968-a6f6-56bef8ec3eb0

📥 Commits

Reviewing files that changed from the base of the PR and between a625708 and 19c345b.

📒 Files selected for processing (4)
  • apps/web/src/app/mypage/withdraw/_hooks/useDeleteMe.ts
  • apps/web/src/app/tournament/[id]/create/_components/invite-friends/InviteFriendsDialog.tsx
  • apps/web/src/app/tournament/[id]/create/by-wish/_hooks/usePostTournamentItemsByWish.ts
  • apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/src/app/mypage/withdraw/_hooks/useDeleteMe.ts
  • apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsx
  • apps/web/src/app/tournament/[id]/create/_components/invite-friends/InviteFriendsDialog.tsx
  • apps/web/src/app/tournament/[id]/create/by-wish/_hooks/usePostTournamentItemsByWish.ts

📝 Walkthrough

Walkthrough

Changes

API 에러 메시지 처리

Layer / File(s) Summary
마이페이지 에러 처리 교체
apps/web/src/app/mypage/edit/_hooks/usePatchMe.ts, apps/web/src/app/mypage/withdraw/_hooks/useDeleteMe.ts
회원정보 수정과 회원탈퇴 실패 시 getApiErrorMessage(error) 결과를 에러 토스트에 표시한다.
토너먼트 에러 토스트 교체
apps/web/src/app/tournament/[id]/create/_components/invite-friends/InviteFriendsDialog.tsx, apps/web/src/app/tournament/[id]/create/by-wish/_hooks/usePostTournamentItemsByWish.ts, apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsx
마감 시각 변경, 위시 아이템 추가, 플레이 링크 생성 실패 시 에러 기반 메시지를 토스트에 표시한다.

이미지 업로드 사전 용량검증

Layer / File(s) Summary
이미지 크기 사전 필터링
apps/web/src/hooks/useImagePicker.ts
5MB를 초과한 파일을 선택 단계에서 제외하고, 유효한 파일만 onSuccess에 전달한다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: soyeong0115

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 서버 detail 기반 에러 통일과 이미지 5MB 사전검증이라는 주요 변경점을 간결하게 잘 요약합니다.
Linked Issues check ✅ Passed 연결 이슈 #305의 4xx detail 노출, getApiErrorMessage 적용, 5MB 사전검증 및 관련 이미지 흐름 적용을 모두 충족합니다.
Out of Scope Changes check ✅ Passed 요구사항과 무관한 변경은 보이지 않으며, 모든 수정이 에러 메시지 통일 또는 이미지 사전검증 범위에 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/305-error-message-policy

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/utils/getApiErrorMessage.ts (1)

1-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

유닛 테스트 부재

정책 분기(상태코드 경계값 500, detail 존재/부재, non-axios 에러)가 여러 개인 공통 유틸인데 테스트가 없습니다. 여러 화면에서 공유되는 만큼 회귀 방지를 위한 테스트 추가를 고려해주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/utils/getApiErrorMessage.ts` around lines 1 - 22, Add unit tests
for getApiErrorMessage to cover the policy branches: axios errors with response
status below 500 and a detail should return that detail, 500+ responses should
fall back, missing detail should fall back, and non-Axios errors should also
return the fallback. Use getApiErrorMessage and DEFAULT_ERROR_MESSAGE as the
main targets so the shared utility’s behavior stays locked down against
regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/web/src/utils/getApiErrorMessage.ts`:
- Around line 1-22: Add unit tests for getApiErrorMessage to cover the policy
branches: axios errors with response status below 500 and a detail should return
that detail, 500+ responses should fall back, missing detail should fall back,
and non-Axios errors should also return the fallback. Use getApiErrorMessage and
DEFAULT_ERROR_MESSAGE as the main targets so the shared utility’s behavior stays
locked down against regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ab0430b5-e624-4823-afc0-8df761980c5e

📥 Commits

Reviewing files that changed from the base of the PR and between ef66bef and f8e92d1.

📒 Files selected for processing (7)
  • apps/web/src/app/mypage/edit/_hooks/usePatchMe.ts
  • apps/web/src/app/mypage/withdraw/_hooks/useDeleteMe.ts
  • apps/web/src/app/tournament/[id]/create/_components/invite-friends/InviteFriendsDialog.tsx
  • apps/web/src/app/tournament/[id]/create/by-wish/_hooks/usePostTournamentItemsByWish.ts
  • apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsx
  • apps/web/src/hooks/useImagePicker.ts
  • apps/web/src/utils/getApiErrorMessage.ts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 새로 생성하지말고 pull 한번 받아서 작업해줄래??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오키 확인해볼게~

…sage-policy

# Conflicts:
#	apps/web/src/utils/getApiErrorMessage.ts
Comment on lines +13 to +19
export const getApiErrorMessage = (error: unknown, fallback?: string): string => {
if (isAxiosError<ApiErrorResponseT>(error)) {
const status = error.response?.status;

if (!status || status >= 500) return '일시적인 오류예요. 잠시 후 다시 시도해 주세요.';
return error.response?.data?.detail ?? '요청을 처리하지 못했어요.';
if (!status || status >= 500)
return fallback ?? '일시적인 오류예요. 잠시 후 다시 시도해 주세요.';
return error.response?.data?.detail ?? fallback ?? '요청을 처리하지 못했어요.';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4) fallback은 제거하는 게 좋아보인당
이 유틸함수의 역할이 에러에러 메시지 추출 규칙 공통화인데 fallback을 사용하게 되면 호출 포인트마다 문구가 달라질 수 있어서 통일하기가 어려울 것 같아

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인

@ychany
ychany merged commit 5e21244 into dev Jul 14, 2026
6 checks passed
@ychany
ychany deleted the refactor/305-error-message-policy branch July 14, 2026 15:32
iOdiO89 pushed a commit that referenced this pull request Jul 19, 2026
* refactor: 에러 문구를 서버 detail 기반으로 통일 + 이미지 5MB 사전검증

* refactor: getApiErrorMessage fallback 파라미터 제거 (문구 통일)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

status 뭉뚱그림 개선 + 413 사전검증

2 participants