Files
sam-react-prod/src/lib/api/error-handler.ts

83 lines
2.3 KiB
TypeScript
Raw Normal View History

// API 에러 핸들링 헬퍼 유틸리티
// API 요청 실패 시 에러 처리 및 사용자 친화적 메시지 생성
/**
* API
* - Error를 HTTP validation errors
*/
export class ApiError extends Error {
constructor(
public status: number,
public message: string,
public errors?: Record<string, string[]>
) {
super(message);
this.name = 'ApiError';
}
}
/**
* API ApiError를 throw
* @param response - fetch Response
* @throws {ApiError} HTTP , , validation errors
*/
export const handleApiError = async (response: Response): Promise<never> => {
const data = await response.json().catch(() => ({}));
// 401 Unauthorized - 토큰 만료 또는 인증 실패
// ✅ 자동 리다이렉트 제거: 각 페이지에서 에러를 직접 처리하도록 변경
// 이를 통해 개발자가 Network 탭에서 에러를 확인할 수 있음
if (response.status === 401) {
throw new ApiError(
401,
data.message || '인증이 필요합니다. 로그인 상태를 확인해주세요.',
data.errors
);
}
// 403 Forbidden - 권한 없음
if (response.status === 403) {
throw new ApiError(
403,
data.message || '접근 권한이 없습니다.',
data.errors
);
}
// 422 Unprocessable Entity - Validation 에러
if (response.status === 422) {
// 상세 validation 에러 로그 출력
console.error('🔴 [API 422 Validation Error]', {
message: data.message,
errors: data.errors,
fullResponse: data
});
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 '알 수 없는 오류가 발생했습니다';
};