143 lines
3.5 KiB
Python
143 lines
3.5 KiB
Python
"""
|
|
Instagram Graph API 커스텀 예외 모듈
|
|
|
|
Instagram API 에러 코드에 맞는 예외 클래스를 정의합니다.
|
|
"""
|
|
|
|
from typing import Optional
|
|
|
|
|
|
class InstagramAPIError(Exception):
|
|
"""
|
|
Instagram API 기본 예외
|
|
|
|
모든 Instagram API 관련 예외의 기본 클래스입니다.
|
|
|
|
Attributes:
|
|
message: 에러 메시지
|
|
code: Instagram API 에러 코드
|
|
subcode: Instagram API 에러 서브코드
|
|
fbtrace_id: Facebook 트레이스 ID (디버깅용)
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: Optional[int] = None,
|
|
subcode: Optional[int] = None,
|
|
fbtrace_id: Optional[str] = None,
|
|
):
|
|
self.message = message
|
|
self.code = code
|
|
self.subcode = subcode
|
|
self.fbtrace_id = fbtrace_id
|
|
super().__init__(self.message)
|
|
|
|
def __str__(self) -> str:
|
|
parts = [self.message]
|
|
if self.code is not None:
|
|
parts.append(f"code={self.code}")
|
|
if self.subcode is not None:
|
|
parts.append(f"subcode={self.subcode}")
|
|
if self.fbtrace_id:
|
|
parts.append(f"fbtrace_id={self.fbtrace_id}")
|
|
return " | ".join(parts)
|
|
|
|
|
|
class AuthenticationError(InstagramAPIError):
|
|
"""
|
|
인증 관련 에러
|
|
|
|
토큰이 만료되었거나, 유효하지 않거나, 앱 권한이 없는 경우 발생합니다.
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
class RateLimitError(InstagramAPIError):
|
|
"""
|
|
Rate Limit 초과 에러
|
|
|
|
시간당 API 호출 제한을 초과한 경우 발생합니다.
|
|
|
|
Attributes:
|
|
retry_after: 재시도까지 대기해야 하는 시간 (초)
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
retry_after: Optional[int] = None,
|
|
code: Optional[int] = 4,
|
|
subcode: Optional[int] = None,
|
|
fbtrace_id: Optional[str] = None,
|
|
):
|
|
super().__init__(message, code, subcode, fbtrace_id)
|
|
self.retry_after = retry_after
|
|
|
|
def __str__(self) -> str:
|
|
base = super().__str__()
|
|
if self.retry_after is not None:
|
|
return f"{base} | retry_after={self.retry_after}s"
|
|
return base
|
|
|
|
|
|
class ContainerStatusError(InstagramAPIError):
|
|
"""
|
|
컨테이너 상태 에러
|
|
|
|
미디어 컨테이너가 ERROR 상태가 되었을 때 발생합니다.
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
class ContainerTimeoutError(InstagramAPIError):
|
|
"""
|
|
컨테이너 타임아웃 에러
|
|
|
|
미디어 컨테이너가 지정된 시간 내에 FINISHED 상태가 되지 않은 경우 발생합니다.
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
# 에러 코드 → 예외 클래스 매핑
|
|
ERROR_CODE_MAPPING: dict[int, type[InstagramAPIError]] = {
|
|
4: RateLimitError,
|
|
17: RateLimitError,
|
|
190: AuthenticationError,
|
|
341: RateLimitError,
|
|
}
|
|
|
|
|
|
def create_exception_from_error(
|
|
message: str,
|
|
code: Optional[int] = None,
|
|
subcode: Optional[int] = None,
|
|
fbtrace_id: Optional[str] = None,
|
|
) -> InstagramAPIError:
|
|
"""
|
|
API 에러 응답에서 적절한 예외 객체 생성
|
|
|
|
Args:
|
|
message: 에러 메시지
|
|
code: API 에러 코드
|
|
subcode: API 에러 서브코드
|
|
fbtrace_id: Facebook 트레이스 ID
|
|
|
|
Returns:
|
|
적절한 예외 클래스의 인스턴스
|
|
"""
|
|
exception_class = InstagramAPIError
|
|
|
|
if code is not None:
|
|
exception_class = ERROR_CODE_MAPPING.get(code, InstagramAPIError)
|
|
|
|
return exception_class(
|
|
message=message,
|
|
code=code,
|
|
subcode=subcode,
|
|
fbtrace_id=fbtrace_id,
|
|
)
|