From 2ceeaf9d14b4cbf8ebdd4fc2569441f4043414f7 Mon Sep 17 00:00:00 2001 From: pbrassel <52356233+pbrassel@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:12:06 +0200 Subject: [PATCH 1/2] feat: loosen the error response model and make all attributes optional --- flame_hub/_exceptions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flame_hub/_exceptions.py b/flame_hub/_exceptions.py index fa1c5b1..ade202b 100644 --- a/flame_hub/_exceptions.py +++ b/flame_hub/_exceptions.py @@ -7,11 +7,11 @@ class ErrorResponse(BaseModel): model_config = ConfigDict(extra="allow") """Configuration so that extra properties may be available.""" - code: str + code: str = "" """Name of the error code.""" status_code: int | None = Field(validation_alias=AliasChoices("status_code", "statusCode"), default=None) """HTTP code of the response.""" - message: str + message: str = "" """The error message.""" issues: list = Field(default_factory=list) """List of issues.""" From 631750095e3efd72b0fc880eea2b1e355cf1e61a Mon Sep 17 00:00:00 2001 From: pbrassel <52356233+pbrassel@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:13:49 +0200 Subject: [PATCH 2/2] feat: save the headers of the unexpected response and the error traceback in case the validation of the response against the model fails in the `HubAPIError` class --- flame_hub/_exceptions.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/flame_hub/_exceptions.py b/flame_hub/_exceptions.py index ade202b..b6c22ee 100644 --- a/flame_hub/_exceptions.py +++ b/flame_hub/_exceptions.py @@ -1,4 +1,5 @@ from json import JSONDecodeError +import traceback import httpx2 as httpx from pydantic import ValidationError, BaseModel, ConfigDict, Field, AliasChoices @@ -26,18 +27,32 @@ class HubAPIError(httpx.HTTPError): The error message. request : :py:class:`httpx.Request` The request which caused the error. + headers : :py:class:`httpx.Headers`, optional + The headers of the unexpected response. error : :py:class:`.ErrorResponse`, optional Parsed response to enrich the error with additional information. + error_model_traceback : :py:class:`str`, optional + Holds the traceback if there is an error while validating the unexpected response against the + :py:class:`.ErrorResponse` model. See Also -------- :py:exc:`.HubAPIError`, :py:func:`.new_hub_api_error_from_response` """ - def __init__(self, message: str, request: httpx.Request, error: ErrorResponse | None = None) -> None: + def __init__( + self, + message: str, + request: httpx.Request, + headers: httpx.Headers = httpx.Headers(), + error: ErrorResponse | None = None, + error_model_traceback: str = "", + ) -> None: super().__init__(message) self._request = request + self.headers = headers self.error_response = error + self.error_model_traceback = error_model_traceback def new_hub_api_error_from_response(r: httpx.Response) -> HubAPIError: @@ -63,6 +78,7 @@ def new_hub_api_error_from_response(r: httpx.Response) -> HubAPIError: """ error_response = None error_message = f"received status code {r.status_code}" + error_model_traceback = "" try: error_response = ErrorResponse(**r.json()) @@ -76,7 +92,6 @@ def new_hub_api_error_from_response(r: httpx.Response) -> HubAPIError: else: error_message += error_response.message except (ValidationError, JSONDecodeError): - # quietly dismiss this error - pass + error_model_traceback = traceback.format_exc() - return HubAPIError(error_message, r.request, error_response) + return HubAPIError(error_message, r.request, r.headers, error_response, error_model_traceback)