유튜브 네트워크 오류 재시도 설정 추가
This commit is contained in:
parent
5903211eb9
commit
8096837b13
@ -433,6 +433,10 @@ class YouTubeAnalyticsService:
|
||||
logger.debug("[YouTubeAnalyticsService._fetch_region] SUCCESS")
|
||||
return result
|
||||
|
||||
# 5xx/네트워크 오류 재시도 설정 (구글 backendError 등 일시적 장애 대응)
|
||||
_MAX_RETRIES = 3
|
||||
_RETRY_BACKOFF_SECONDS = (0.5, 1.0, 2.0)
|
||||
|
||||
async def _call_api(
|
||||
self,
|
||||
params: dict[str, str],
|
||||
@ -453,15 +457,18 @@ class YouTubeAnalyticsService:
|
||||
Raises:
|
||||
YouTubeQuotaExceededError: 할당량 초과 (429)
|
||||
YouTubeAuthError: 인증 실패 (401, 403)
|
||||
YouTubeAPIError: 기타 API 오류
|
||||
YouTubeAPIError: 기타 API 오류 (5xx/네트워크 오류는 최대 3회 재시도 후 발생)
|
||||
|
||||
Note:
|
||||
- 타임아웃: 30초
|
||||
- 할당량 초과 시 자동으로 YouTubeQuotaExceededError 발생
|
||||
- 인증 실패 시 자동으로 YouTubeAuthError 발생
|
||||
- 5xx 응답 및 네트워크 오류는 지수 백오프(0.5s→1s→2s)로 최대 3회 재시도
|
||||
"""
|
||||
headers = {"Authorization": f"Bearer {access_token}"}
|
||||
|
||||
last_error: Exception | None = None
|
||||
for attempt in range(self._MAX_RETRIES + 1):
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
response = await client.get(
|
||||
@ -488,16 +495,29 @@ class YouTubeAnalyticsService:
|
||||
return response.json()
|
||||
|
||||
except (YouTubeAuthError, YouTubeQuotaExceededError):
|
||||
raise # 이미 처리된 예외는 그대로 전파
|
||||
raise # 이미 처리된 예외는 재시도 없이 그대로 전파
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(
|
||||
f"[YouTubeAnalyticsService._call_api] HTTP_ERROR - "
|
||||
f"status={e.response.status_code}, body={e.response.text[:500]}"
|
||||
)
|
||||
# 4xx는 재시도해도 동일하게 실패하므로 즉시 전파, 5xx만 재시도
|
||||
if e.response.status_code < 500:
|
||||
raise YouTubeAPIError(f"HTTP {e.response.status_code}")
|
||||
last_error = YouTubeAPIError(f"HTTP {e.response.status_code}")
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f"[YouTubeAnalyticsService._call_api] REQUEST_ERROR - {e}")
|
||||
raise YouTubeAPIError(f"네트워크 오류: {e}")
|
||||
last_error = YouTubeAPIError(f"네트워크 오류: {e}")
|
||||
except Exception as e:
|
||||
logger.error(f"[YouTubeAnalyticsService._call_api] UNEXPECTED_ERROR - {e}")
|
||||
raise YouTubeAPIError(f"알 수 없는 오류: {e}")
|
||||
|
||||
if attempt < self._MAX_RETRIES:
|
||||
backoff = self._RETRY_BACKOFF_SECONDS[attempt]
|
||||
logger.warning(
|
||||
f"[YouTubeAnalyticsService._call_api] RETRY {attempt + 1}/{self._MAX_RETRIES} "
|
||||
f"in {backoff}s - {last_error}"
|
||||
)
|
||||
await asyncio.sleep(backoff)
|
||||
|
||||
raise last_error
|
||||
|
||||
Loading…
Reference in New Issue
Block a user