make the retry logic faster

This commit is contained in:
Luiz Felipe Costa 2025-09-23 22:39:45 -03:00
parent f5d7a5ab5b
commit 2dd0626a3a

View file

@ -6,7 +6,7 @@ from typing import Any, Awaitable, Callable, Optional, TypeVar
from pydantic import BaseModel
from ..types.errors import NetworkError
from ..types.errors import NetworkError, AuthenticationError, GhostApiError, ValidationError
from .logging import get_logger
T = TypeVar("T")
@ -22,6 +22,44 @@ class RetryConfig(BaseModel):
jitter: bool = True
def _should_retry(exception: Exception) -> bool:
"""Determine if an exception should trigger a retry.
Only retry transient network errors, not client errors or authentication issues.
"""
# Retry network errors (connection issues, timeouts)
if isinstance(exception, NetworkError):
return True
# Don't retry authentication errors - these need manual intervention
if isinstance(exception, AuthenticationError):
return False
# Don't retry validation errors - the request is malformed
if isinstance(exception, ValidationError):
return False
# For Ghost API errors, only retry 5xx server errors, not 4xx client errors
if isinstance(exception, GhostApiError):
# Check if the error context indicates a server error (5xx)
if exception.context and "HTTP 5" in exception.context:
return True
# Check if it's a rate limiting error (429) - should be retried
if exception.context and "HTTP 429" in exception.context:
return True
# All other Ghost API errors (4xx) should not be retried
return False
# For unknown exceptions, be conservative and retry (could be network issues)
# but log a warning so we can identify what should/shouldn't be retried
logger.warning(
"Unknown exception type encountered in retry logic",
exception_type=type(exception).__name__,
exception=str(exception)
)
return True
async def with_retry(
operation: Callable[[], Awaitable[T]],
config: Optional[RetryConfig] = None,
@ -39,6 +77,17 @@ async def with_retry(
except Exception as e:
last_exception = e
# Check if this exception should trigger a retry
if not _should_retry(e):
logger.debug(
"Exception not suitable for retry, failing immediately",
attempt=attempt,
exception_type=type(e).__name__,
error=str(e),
request_id=request_id,
)
break
if attempt == config.max_retries:
logger.error(
"Operation failed after all retries",