Files
sam-react-prod/claudedocs/architecture/[IMPL-2026-02-23] phase1-item4-error-format.md
유병철 07374c826c refactor(WEB): claudedocs 재정리 및 AuthContext/Zustand/유틸 코드 개선
- claudedocs 폴더 구조 재정리: archive/sessions, guides/migration·mobile·universal-list, refactoring 분류
- 오래된 세션 컨텍스트/체크리스트 문서 정리 (아카이브 이동 또는 삭제)
- AuthContext → authStore(Zustand) 전환 시작, RootProvider 간소화
- GenericCRUDDialog 공통 다이얼로그 컴포넌트 추가
- PermissionDialog 삭제 → GenericCRUDDialog로 대체
- RankDialog/TitleDialog GenericCRUDDialog 기반으로 리팩토링
- toast-utils.ts 삭제 (미사용)
- fileDownload.ts 개선, excel-download.ts 정리
- menuStore/themeStore Zustand 셀렉터 최적화
- useColumnSettings/useTableColumnStore 기능 보강
- 세금계산서/견적/작업자화면/결재 등 소규모 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:17:13 +09:00

3.8 KiB

Phase 1-4: 에러 메시지 포맷 통합 (formatApiError 제거)

난이도: 저 | 영향도: 🟡 API 레이어 정리 | 예상 변경: 1파일 삭제


현황 요약

에러 메시지 포맷팅 함수가 2곳에 중복:

파일 함수 외부 사용처
src/lib/api/error-handler.ts:122 getErrorMessage() 5+ 파일 (활발히 사용)
src/lib/api/toast-utils.ts:106 formatApiError() 0건 (dead code)

또한 SHOW_ERROR_CODE 상수도 양쪽에 중복 정의됨.


핵심 발견: toast-utils.ts 전체가 dead code

from '@/lib/api/toast-utils' 를 import하는 파일이 0건.

toast-utils.ts 내보내는 함수 전부 미사용:
- toastApiError()    → 0 import
- toastSuccess()     → 0 import
- toastWarning()     → 0 import
- toastInfo()        → 0 import
- formatApiError()   → 0 import

현재 프로젝트에서 에러 토스트 표시는 직접 toast.error(getErrorMessage(err)) 패턴으로 처리 중.


작업 내역

Step 1: src/lib/api/toast-utils.ts 삭제

파일 전체가 dead code이므로 삭제.

Step 2: (선택) 유용한 헬퍼를 error-handler.ts로 이동

toastApiError() 함수는 validation 에러의 첫 번째 필드를 표시하는 로직이 있어, 향후 유용할 수 있으면 error-handler.ts 하단에 통합 가능.

// src/lib/api/error-handler.ts 하단에 추가 (선택)
import { toast } from 'sonner';

export function toastApiError(error: unknown, fallbackMessage = '오류가 발생했습니다.'): void {
  if (error instanceof ApiError && error.errors && SHOW_ERROR_CODE) {
    const firstField = Object.keys(error.errors)[0];
    if (firstField) {
      toast.error(`${getErrorMessage(error)}\n${firstField}: ${error.errors[firstField][0]}`);
      return;
    }
  }
  toast.error(getErrorMessage(error) || fallbackMessage);
}

이 step은 선택. 현재 사용처가 없으므로 당장은 삭제만으로 충분.

Step 3: 검증

npx tsc --noEmit

toast-utils.ts를 삭제해도 외부 import가 없으므로 타입 에러 없음.


관련 파일 참조

활발히 사용 중인 함수 (변경 없음)

getErrorMessage() 사용처 (error-handler.ts에서 export):

  • src/contexts/ItemMasterContext.tsx (line 7, 589, 682)
  • src/components/items/ItemMasterDataManagement/hooks/usePageManagement.ts (line 7, 122, 159, 198, 219)
  • src/components/items/ItemMasterDataManagement/hooks/useImportManagement.ts (line 5, 58, 80, 92)
  • src/components/items/ItemMasterDataManagement/hooks/useInitialDataLoading.ts (line 7, 130)
  • src/app/[locale]/(protected)/sales/client-management-sales-admin/page.tsx (line 40, 301, 347)

삭제 대상

  • src/lib/api/toast-utils.ts (전체 116줄)

중복 구조 비교

error-handler.ts                    toast-utils.ts (삭제 대상)
─────────────────                   ──────────────────────────
const SHOW_ERROR_CODE = true;       const SHOW_ERROR_CODE = true;  ← 중복

getErrorMessage(error):             formatApiError(error):
  DuplicateCodeError → [status]       ApiError → [status] msg
  ApiError → [status] msg             else → getErrorMessage()   ← 결국 위임
  Error → .message
  unknown → 기본 메시지
                                    toastApiError(error):
                                      DuplicateCodeError → toast  ← getErrorMessage와 동일 로직
                                      ApiError → toast
                                      Error → toast
                                      unknown → toast

formatApiError는 결국 getErrorMessage를 호출하는 래퍼에 불과. 삭제해도 기능 손실 없음.