// API 에러 핸들링 헬퍼 유틸리티 // API 요청 실패 시 에러 처리 및 사용자 친화적 메시지 생성 /** * API 에러 클래스 * - 표준 Error를 확장하여 HTTP 상태 코드와 validation errors 포함 */ export class ApiError extends Error { constructor( public status: number, public message: string, public errors?: Record ) { super(message); this.name = 'ApiError'; } } /** * API 응답 에러를 처리하고 ApiError를 throw * @param response - fetch Response 객체 * @throws {ApiError} HTTP 상태 코드, 메시지, validation errors 포함 */ export const handleApiError = async (response: Response): Promise => { const data = await response.json().catch(() => ({})); // 401 Unauthorized - 토큰 만료 또는 인증 실패 if (response.status === 401) { // 로그인 페이지로 리다이렉트 if (typeof window !== 'undefined') { // 현재 페이지 URL을 저장 (로그인 후 돌아오기 위함) const currentPath = window.location.pathname + window.location.search; sessionStorage.setItem('redirectAfterLogin', currentPath); // 로그인 페이지로 이동 window.location.href = '/login?session=expired'; } throw new ApiError( 401, '인증이 만료되었습니다. 다시 로그인해주세요.', data.errors ); } // 403 Forbidden - 권한 없음 if (response.status === 403) { throw new ApiError( 403, data.message || '접근 권한이 없습니다.', data.errors ); } // 422 Unprocessable Entity - Validation 에러 if (response.status === 422) { throw new ApiError( 422, data.message || '입력값을 확인해주세요.', data.errors ); } // 기타 에러 throw new ApiError( response.status, data.message || '서버 오류가 발생했습니다', data.errors ); }; /** * 에러 객체에서 사용자 친화적인 메시지 추출 * @param error - 발생한 에러 객체 (ApiError, Error, unknown) * @returns 사용자에게 표시할 에러 메시지 */ export const getErrorMessage = (error: unknown): string => { if (error instanceof ApiError) { return error.message; } if (error instanceof Error) { return error.message; } return '알 수 없는 오류가 발생했습니다'; };