from functools import cached_property from typing import Any import httpx from pydantic import ValidationError from dmp.adapters.fivetran.models import SimpleResponse class FivetranClientError(Exception): code = "fivetran_client_error" message = "Fivetran client error" def __init__( self, message: str | None = None, *, request: httpx.Request | None = None, response: httpx.Response | None = None, ): if message is not None: self.message = message self.request = request self.response = response @property def status_code(self) -> int: if self.response: return self.response.status_code return 500 @cached_property def response_obj(self) -> SimpleResponse | None: if self.response: try: return SimpleResponse.model_validate_json(self.response.content) except ValidationError: pass return None @cached_property def response_data(self) -> dict[str, Any]: if self.response_obj: return self.response_obj.model_dump() return {} @cached_property def log_msg(self) -> str: if self.response_obj: return self.response_obj.message or self.message return self.message @property def log_extra(self) -> dict[str, Any]: extra: dict[str, Any] = {} if self.request: extra["fivetran_request_method"] = self.request.method extra["fivetran_request_path"] = self.request.url.path if self.response: extra["fivetran_response_status_code"] = self.response.status_code if self.response_obj: extra["fivetran_response_error"] = self.response_data return extra class FivetranClientTimeoutError(FivetranClientError): code = "fivetran_client_timeout_error" message = "Fivetran client timeout error"