Skip to content

에러 처리

14.3.1. HTTP 상태코드별 처리

  • API 응답 에러는 HTTP 상태코드를 기준으로 분류하여 처리합니다.
  • 각 상태코드에 대한 처리 전략을 사전에 정의하고, 일관되게 적용해야 합니다.
상태코드의미처리 전략
400잘못된 요청서버 응답의 유효성 검증 메시지를 사용자에게 표시합니다
401인증 실패토큰 갱신을 시도합니다. 갱신 실패 시 로그인 페이지로 리다이렉트합니다
403권한 없음접근 권한 부족 안내 메시지를 표시합니다
404리소스 없음요청한 데이터를 찾을 수 없음을 안내합니다
409충돌데이터 충돌 상황을 안내하고, 새로고침을 유도합니다
422처리 불가서버 유효성 검증 실패 메시지를 폼 필드에 매핑합니다
500서버 오류일반적인 서버 오류 메시지를 표시합니다. 상세 내용은 노출하지 않습니다
502/503서비스 불가서비스 점검 또는 일시적 오류 안내를 표시합니다

14.3.2. 네트워크 에러

  • 서버 응답이 없는 경우(error.responseundefined)는 네트워크 에러로 분류합니다.
  • 네트워크 에러와 타임아웃 에러는 구분하여 처리합니다.
typescript
// src/api/utils/error.ts
import type { AxiosError } from 'axios'

export function isNetworkError(error: AxiosError): boolean {
  return !error.response && error.code !== 'ECONNABORTED'
}

export function isTimeoutError(error: AxiosError): boolean {
  return error.code === 'ECONNABORTED'
}
  • 오프라인 상태 감지는 navigator.onLine 속성과 online/offline 이벤트 리스너를 활용합니다.
  • Composable 함수(useNetworkStatus)로 구현하여 컴포넌트에서 반응형으로 사용합니다.

14.3.3. 사용자 피드백

  • API 에러 발생 시 사용자에게 적절한 피드백을 제공해야 합니다.
  • 에러 메시지는 표준화된 형식으로 관리합니다.
typescript
// src/api/utils/notify.ts
const ERROR_MESSAGES: Record<string, string> = {
  NETWORK_ERROR: '네트워크 연결을 확인해 주십시오.',
  TIMEOUT_ERROR: '요청 시간이 초과되었습니다. 다시 시도해 주십시오.',
  UNAUTHORIZED: '인증이 만료되었습니다. 다시 로그인해 주십시오.',
  FORBIDDEN: '접근 권한이 없습니다.',
  NOT_FOUND: '요청하신 데이터를 찾을 수 없습니다.',
  SERVER_ERROR: '서버 오류가 발생했습니다. 잠시 후 다시 시도해 주십시오.',
  DEFAULT: '오류가 발생했습니다.',
}

export function getErrorMessage(code: string): string {
  return ERROR_MESSAGES[code] ?? ERROR_MESSAGES.DEFAULT
}
  • 서버에서 전달하는 에러 메시지가 있는 경우, 해당 메시지를 우선 사용합니다.
  • 서버 메시지가 없거나 기술적 내용인 경우, 표준 메시지로 대체합니다.

14.3.4. 글로벌 에러 핸들러

  • Axios 에러를 애플리케이션 표준 에러 객체로 변환하는 핸들러를 구현합니다.
  • AppError 클래스를 정의하여 에러 타입을 통일합니다.
typescript
// src/api/errors/AppError.ts
export class AppError extends Error {
  readonly status: number
  readonly code: string

  constructor(status: number, code: string, message: string) {
    super(message)
    this.name = 'AppError'
    this.status = status
    this.code = code
  }
}
typescript
// src/api/errors/handleApiError.ts
import type { AxiosError } from 'axios'
import { AppError } from './AppError'
import { isNetworkError, isTimeoutError } from '@/api/utils/error'

export function handleApiError(error: AxiosError): AppError {
  if (isTimeoutError(error)) {
    return new AppError(0, 'TIMEOUT_ERROR', '요청 시간 초과')
  }
  if (isNetworkError(error)) {
    return new AppError(0, 'NETWORK_ERROR', '네트워크 오류')
  }

  const status = error.response?.status ?? 0
  const data = error.response?.data as Record<string, string> | undefined

  return new AppError(status, data?.code ?? 'UNKNOWN_ERROR', data?.message ?? '알 수 없는 오류')
}
  • 개별 API 호출에서 handleApiError를 사용하여 에러를 변환합니다.
  • 공통 처리가 필요한 경우 응답 인터셉터에서 변환을 수행합니다.

TIENIPIA QUALIFIED STANDARD