Skip to content

Commit f9b110a

Browse files
Error handling initial
1 parent c2c7ce6 commit f9b110a

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

workflowai/core/client/api.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from typing import Any, AsyncIterator, Literal, Optional, TypeVar, Union, overload
23

34
import httpx
@@ -34,7 +35,7 @@ def _client(self) -> httpx.AsyncClient:
3435
async def get(self, path: str, returns: type[_R], query: Union[dict[str, Any], None] = None) -> _R:
3536
async with self._client() as client:
3637
response = await client.get(path, params=query)
37-
response.raise_for_status()
38+
await self.raise_for_status(response)
3839
return TypeAdapter(returns).validate_python(response.json())
3940

4041
@overload
@@ -55,7 +56,7 @@ async def post(
5556
content=data.model_dump_json(exclude_none=True),
5657
headers={"Content-Type": "application/json"},
5758
)
58-
response.raise_for_status()
59+
await self.raise_for_status(response)
5960
if not returns:
6061
return None
6162
return TypeAdapter(returns).validate_python(response.json())
@@ -78,18 +79,22 @@ async def patch(
7879
content=data.model_dump_json(exclude_none=True),
7980
headers={"Content-Type": "application/json"},
8081
)
81-
response.raise_for_status()
82+
await self.raise_for_status(response)
8283
if not returns:
8384
return None
8485
return TypeAdapter(returns).validate_python(response.json())
8586

8687
async def delete(self, path: str) -> None:
8788
async with self._client() as client:
8889
response = await client.delete(path)
89-
response.raise_for_status()
90+
await self.raise_for_status(response)
9091

9192
def _extract_error(self, data: Union[bytes, str], exception: Optional[Exception] = None) -> WorkflowAIError:
9293
try:
94+
data_dict = json.loads(data)
95+
if next(iter(data_dict.keys())) == "detail":
96+
data_dict = {"error": {"detail": data_dict["detail"]}}
97+
data = json.dumps(data_dict)
9398
res = ErrorResponse.model_validate_json(data)
9499
return WorkflowAIError(res.error, task_run_id=res.task_run_id)
95100
except ValidationError:
@@ -122,3 +127,7 @@ async def stream(
122127
yield returns.model_validate_json(payload)
123128
except ValidationError as e:
124129
raise self._extract_error(payload, e) from None
130+
131+
async def raise_for_status(self, response: httpx.Response):
132+
if response.status_code != 200:
133+
raise self._extract_error(response.content) from None

workflowai/core/domain/errors.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from typing import Any, Literal, Optional, Union
23

34
from pydantic import BaseModel
@@ -71,3 +72,13 @@ class WorkflowAIError(Exception):
7172
def __init__(self, error: BaseError, task_run_id: Optional[str] = None):
7273
self.error = error
7374
self.task_run_id = task_run_id
75+
76+
def __str__(self):
77+
error_dict = {
78+
"message": self.error.message,
79+
"code": self.error.code,
80+
"status_code": self.error.status_code,
81+
"details": self.error.details,
82+
"task_run_id": self.task_run_id,
83+
}
84+
return json.dumps(error_dict, indent=4)

0 commit comments

Comments
 (0)