o2o-castad-backend/app/dashboard/exceptions.py

196 lines
6.2 KiB
Python

"""
Dashboard Exceptions
Dashboard API 관련 예외 클래스를 정의합니다.
"""
from fastapi import status
class DashboardException(Exception):
"""Dashboard 기본 예외"""
def __init__(
self,
message: str,
status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
code: str = "DASHBOARD_ERROR",
):
self.message = message
self.status_code = status_code
self.code = code
super().__init__(self.message)
# =============================================================================
# YouTube Analytics API 관련 예외
# =============================================================================
class YouTubeAPIException(DashboardException):
"""YouTube Analytics API 관련 예외 기본 클래스"""
def __init__(
self,
message: str = "YouTube Analytics API 호출 중 오류가 발생했습니다.",
status_code: int = status.HTTP_502_BAD_GATEWAY,
code: str = "YOUTUBE_API_ERROR",
):
super().__init__(message, status_code, code)
class YouTubeAPIError(YouTubeAPIException):
"""YouTube Analytics API 일반 오류"""
def __init__(self, detail: str = ""):
error_message = "YouTube Analytics API 호출에 실패했습니다."
if detail:
error_message += f" ({detail})"
super().__init__(
message=error_message,
status_code=status.HTTP_502_BAD_GATEWAY,
code="YOUTUBE_API_FAILED",
)
class YouTubeAuthError(YouTubeAPIException):
"""YouTube 인증 실패"""
def __init__(self, detail: str = ""):
error_message = "YouTube 인증에 실패했습니다. 계정 재연동이 필요합니다."
if detail:
error_message += f" ({detail})"
super().__init__(
message=error_message,
status_code=status.HTTP_401_UNAUTHORIZED,
code="YOUTUBE_AUTH_FAILED",
)
class YouTubeQuotaExceededError(YouTubeAPIException):
"""YouTube API 할당량 초과"""
def __init__(self):
super().__init__(
message="YouTube API 일일 할당량이 초과되었습니다. 내일 다시 시도해주세요.",
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
code="YOUTUBE_QUOTA_EXCEEDED",
)
class YouTubeDataNotFoundError(YouTubeAPIException):
"""YouTube Analytics 데이터 없음"""
def __init__(self, detail: str = ""):
error_message = "YouTube Analytics 데이터를 찾을 수 없습니다."
if detail:
error_message += f" ({detail})"
super().__init__(
message=error_message,
status_code=status.HTTP_404_NOT_FOUND,
code="YOUTUBE_DATA_NOT_FOUND",
)
# =============================================================================
# 계정 연동 관련 예외
# =============================================================================
class YouTubeAccountNotConnectedError(DashboardException):
"""YouTube 계정 미연동"""
def __init__(self):
super().__init__(
message="YouTube 계정이 연동되어 있지 않습니다. 먼저 YouTube 계정을 연동해주세요.",
status_code=status.HTTP_403_FORBIDDEN,
code="YOUTUBE_NOT_CONNECTED",
)
class YouTubeAccountSelectionRequiredError(DashboardException):
"""여러 YouTube 계정이 연동된 경우 계정 선택 필요"""
def __init__(self):
super().__init__(
message="연결된 YouTube 계정이 여러 개입니다. platform_user_id 파라미터로 사용할 계정을 선택해주세요.",
status_code=status.HTTP_400_BAD_REQUEST,
code="YOUTUBE_ACCOUNT_SELECTION_REQUIRED",
)
class YouTubeAccountNotFoundError(DashboardException):
"""지정한 YouTube 계정을 찾을 수 없음"""
def __init__(self):
super().__init__(
message="지정한 YouTube 계정을 찾을 수 없습니다.",
status_code=status.HTTP_404_NOT_FOUND,
code="YOUTUBE_ACCOUNT_NOT_FOUND",
)
class YouTubeTokenExpiredError(DashboardException):
"""YouTube 토큰 만료"""
def __init__(self):
super().__init__(
message="YouTube 인증이 만료되었습니다. 계정을 재연동해주세요.",
status_code=status.HTTP_401_UNAUTHORIZED,
code="YOUTUBE_TOKEN_EXPIRED",
)
# =============================================================================
# 데이터 관련 예외
# =============================================================================
class NoVideosFoundError(DashboardException):
"""업로드된 영상 없음"""
def __init__(self):
super().__init__(
message="업로드된 YouTube 영상이 없습니다. 먼저 영상을 업로드해주세요.",
status_code=status.HTTP_404_NOT_FOUND,
code="NO_VIDEOS_FOUND",
)
class DashboardDataError(DashboardException):
"""대시보드 데이터 처리 오류"""
def __init__(self, detail: str = ""):
error_message = "대시보드 데이터 처리 중 오류가 발생했습니다."
if detail:
error_message += f" ({detail})"
super().__init__(
message=error_message,
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
code="DASHBOARD_DATA_ERROR",
)
# =============================================================================
# 캐싱 관련 예외 (경고용, 실제로는 raise하지 않고 로깅만 사용)
# =============================================================================
class CacheError(DashboardException):
"""캐시 작업 오류
Note:
이 예외는 실제로 raise되지 않고,
캐시 실패 시 로깅만 하고 원본 데이터를 반환합니다.
"""
def __init__(self, operation: str, detail: str = ""):
error_message = f"캐시 {operation} 작업 중 오류가 발생했습니다."
if detail:
error_message += f" ({detail})"
super().__init__(
message=error_message,
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
code="CACHE_ERROR",
)