Skip to content

Commit f040f10

Browse files
authored
feat: add new storage error class (#313)
1 parent 9d9d3a2 commit f040f10

File tree

5 files changed

+57
-30
lines changed

5 files changed

+57
-30
lines changed

storage3/_async/bucket.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
from typing import Any, Optional
44

5-
from httpx import HTTPError, Response
5+
from httpx import HTTPStatusError, Response
66

7+
from ..exceptions import StorageApiError
78
from ..types import CreateOrUpdateBucketOptions, RequestMethod
8-
from ..utils import AsyncClient, StorageException
9+
from ..utils import AsyncClient
910
from .file_api import AsyncBucket
1011

1112
__all__ = ["AsyncStorageBucketAPI"]
@@ -23,13 +24,12 @@ async def _request(
2324
url: str,
2425
json: Optional[dict[Any, Any]] = None,
2526
) -> Response:
26-
response = await self._client.request(method, url, json=json)
2727
try:
28+
response = await self._client.request(method, url, json=json)
2829
response.raise_for_status()
29-
except HTTPError:
30-
raise StorageException(
31-
{**response.json(), "statusCode": response.status_code}
32-
)
30+
except HTTPStatusError as exc:
31+
resp = exc.response.json()
32+
raise StorageApiError(resp["message"], resp["error"], resp["statusCode"])
3333

3434
return response
3535

storage3/_async/file_api.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
import urllib.parse
44
from dataclasses import dataclass, field
55
from io import BufferedReader, FileIO
6-
from json import JSONDecodeError
76
from pathlib import Path
87
from typing import Any, Literal, Optional, Union, cast
98

10-
from httpx import HTTPError, Response
9+
from httpx import HTTPStatusError, Response
1110

1211
from ..constants import DEFAULT_FILE_OPTIONS, DEFAULT_SEARCH_OPTIONS
12+
from ..exceptions import StorageApiError
1313
from ..types import (
1414
BaseBucket,
1515
CreateSignedURLsOptions,
@@ -47,12 +47,9 @@ async def _request(
4747
method, url, headers=headers or {}, json=json, files=files, **kwargs
4848
)
4949
response.raise_for_status()
50-
except HTTPError:
51-
try:
52-
resp = response.json()
53-
raise StorageException({**resp, "statusCode": response.status_code})
54-
except JSONDecodeError:
55-
raise StorageException({"statusCode": response.status_code})
50+
except HTTPStatusError as exc:
51+
resp = exc.response.json()
52+
raise StorageApiError(resp["message"], resp["error"], resp["statusCode"])
5653

5754
return response
5855

storage3/_sync/bucket.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
from typing import Any, Optional
44

5-
from httpx import HTTPError, Response
5+
from httpx import HTTPStatusError, Response
66

7+
from ..exceptions import StorageApiError
78
from ..types import CreateOrUpdateBucketOptions, RequestMethod
8-
from ..utils import StorageException, SyncClient
9+
from ..utils import SyncClient
910
from .file_api import SyncBucket
1011

1112
__all__ = ["SyncStorageBucketAPI"]
@@ -23,13 +24,12 @@ def _request(
2324
url: str,
2425
json: Optional[dict[Any, Any]] = None,
2526
) -> Response:
26-
response = self._client.request(method, url, json=json)
2727
try:
28+
response = self._client.request(method, url, json=json)
2829
response.raise_for_status()
29-
except HTTPError:
30-
raise StorageException(
31-
{**response.json(), "statusCode": response.status_code}
32-
)
30+
except HTTPStatusError as exc:
31+
resp = exc.response.json()
32+
raise StorageApiError(resp["message"], resp["error"], resp["statusCode"])
3333

3434
return response
3535

storage3/_sync/file_api.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
import urllib.parse
44
from dataclasses import dataclass, field
55
from io import BufferedReader, FileIO
6-
from json import JSONDecodeError
76
from pathlib import Path
87
from typing import Any, Literal, Optional, Union, cast
98

10-
from httpx import HTTPError, Response
9+
from httpx import HTTPStatusError, Response
1110

1211
from ..constants import DEFAULT_FILE_OPTIONS, DEFAULT_SEARCH_OPTIONS
12+
from ..exceptions import StorageApiError
1313
from ..types import (
1414
BaseBucket,
1515
CreateSignedURLsOptions,
@@ -47,12 +47,9 @@ def _request(
4747
method, url, headers=headers or {}, json=json, files=files, **kwargs
4848
)
4949
response.raise_for_status()
50-
except HTTPError:
51-
try:
52-
resp = response.json()
53-
raise StorageException({**resp, "statusCode": response.status_code})
54-
except JSONDecodeError:
55-
raise StorageException({"statusCode": response.status_code})
50+
except HTTPStatusError as exc:
51+
resp = exc.response.json()
52+
raise StorageApiError(resp["message"], resp["error"], resp["statusCode"])
5653

5754
return response
5855

storage3/exceptions.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from typing import TypedDict
2+
3+
from .utils import StorageException
4+
5+
6+
class StorageApiErrorDict(TypedDict):
7+
name: str
8+
message: str
9+
status: int
10+
11+
12+
class StorageApiError(StorageException):
13+
"""Error raised when an operation on the storage API fails."""
14+
15+
def __init__(self, message: str, code: str, status: int) -> None:
16+
error_message = "{{'statusCode': {}, 'error': {}, 'message': {}}}".format(
17+
status,
18+
code,
19+
message,
20+
)
21+
super().__init__(error_message)
22+
self.name = "StorageApiError"
23+
self.message = message
24+
self.code = code
25+
self.status = status
26+
27+
def to_dict(self) -> StorageApiErrorDict:
28+
return {
29+
"name": self.name,
30+
"code": self.code,
31+
"message": self.message,
32+
"status": self.status,
33+
}

0 commit comments

Comments
 (0)