from functools import cached_property from typing import Any import httpx from fansifter_common.httpclient.exceptions import HTTPClientError from pydantic import ValidationError from dmp.adapters.tiktok.constants import ERROR_CODE_PERMISSIONS_ERROR from dmp.adapters.tiktok.models import ErrorResponse class TikTokClientError(HTTPClientError): def __init__( self, message: str = "TikTok client error", *, request: httpx.Request | None = None, response: httpx.Response | None = None, ): self.message = message self.request = request self.response = response def __str__(self) -> str: return self.message @property def status_code(self) -> int: if self.response: return self.response.status_code return 500 @cached_property def tiktok_error(self) -> ErrorResponse | None: if self.response: try: error_response = ErrorResponse.model_validate_json( self.response.content ) except ValidationError: pass else: return error_response return None @property def log_msg(self) -> str: if self.tiktok_error: return self.tiktok_error.message or self.message return self.message @property def log_extra(self) -> dict[str, Any]: extra: dict[str, Any] = {} if self.request: extra["tiktok_request_method"] = self.request.method extra["tiktok_request_path"] = self.request.url.path if self.tiktok_error: extra["tiktok_error_status_code"] = self.tiktok_error.code extra["tiktok_error_error"] = self.tiktok_error.message return extra @property def is_permissions_error(self) -> bool: if self.tiktok_error: return self.tiktok_error.code == ERROR_CODE_PERMISSIONS_ERROR return False