Model/infrastructure/hubspot/scrubbed_calls.py
Daniel Roth ed08a6adfe HubSpot clients share one scrubbed-retry call policy 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:02:22 +00:00

45 lines
1.6 KiB
Python

import json
from typing import Any, Callable, Dict, Optional, TypeVar, cast
from infrastructure.hubspot.errors import HubspotRequestError
from infrastructure.hubspot.retry import call_with_retry
T = TypeVar("T")
def scrubbed(error: Exception) -> HubspotRequestError:
"""Reduce an SDK error to non-PII diagnostics, dropping the body.
Each HubSpot sub-module ships its own ApiException class with no shared
base beyond Exception, so the fields are read by duck-typing.
"""
status = getattr(error, "status", None)
status_code = status if isinstance(status, int) else None
category: Optional[str] = None
correlation_id: Optional[str] = None
try:
parsed: Any = json.loads(getattr(error, "body", None) or "")
if isinstance(parsed, dict):
details = cast(Dict[str, Any], parsed)
raw_category = details.get("category")
raw_correlation_id = details.get("correlationId")
category = raw_category if isinstance(raw_category, str) else None
correlation_id = (
raw_correlation_id if isinstance(raw_correlation_id, str) else None
)
except ValueError:
pass
return HubspotRequestError(
status_code=status_code, category=category, correlation_id=correlation_id
)
def scrubbed_call_with_retry(fn: Callable[[], T]) -> T:
"""Run one SDK call under the shared retry policy, scrubbed on failure."""
try:
return call_with_retry(fn)
except Exception as error:
# `from None` keeps the body-carrying SDK error out of tracebacks.
raise scrubbed(error) from None