Skip to content

Commit 747f54e

Browse files
committed
[errors] minor fixes to errors handling
1 parent b4f1550 commit 747f54e

File tree

5 files changed

+50
-22
lines changed

5 files changed

+50
-22
lines changed

android_sms_gateway/ahttp.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
7777
async def _process_response(self, response: aiohttp.ClientResponse) -> dict:
7878
try:
7979
response.raise_for_status()
80+
if response.status == 204:
81+
return {}
82+
8083
return await response.json()
8184
except aiohttp.ClientResponseError as e:
8285
# Extract error message from response if available
@@ -89,7 +92,9 @@ async def _process_response(self, response: aiohttp.ClientResponse) -> dict:
8992

9093
# Use the error mapping to create appropriate exception
9194
error_message = str(e) or "HTTP request failed"
92-
raise error_from_status(error_message, response.status, error_data)
95+
raise error_from_status(
96+
error_message, response.status, error_data
97+
) from e
9398

9499
async def get(
95100
self, url: str, *, headers: t.Optional[t.Dict[str, str]] = None
@@ -183,6 +188,9 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
183188
async def _process_response(self, response: httpx.Response) -> dict:
184189
try:
185190
response.raise_for_status()
191+
if response.status_code == 204:
192+
return {}
193+
186194
return response.json()
187195
except httpx.HTTPStatusError as e:
188196
# Extract error message from response if available
@@ -195,7 +203,9 @@ async def _process_response(self, response: httpx.Response) -> dict:
195203

196204
# Use the error mapping to create appropriate exception
197205
error_message = str(e) or "HTTP request failed"
198-
raise error_from_status(error_message, response.status_code, error_data)
206+
raise error_from_status(
207+
error_message, response.status_code, error_data
208+
) from e
199209

200210
async def get(
201211
self, url: str, *, headers: t.Optional[t.Dict[str, str]] = None

android_sms_gateway/domain.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import base64
22
import dataclasses
33
import datetime
4+
import enum
45
import typing as t
56

67
from .enums import ProcessState, WebhookEvent, MessagePriority
@@ -18,7 +19,7 @@ class Message:
1819
1920
Attributes:
2021
phone_numbers (List[str]): Recipients (phone numbers).
21-
tex_message (Optional[TextMessage]): Text message.
22+
text_message (Optional[TextMessage]): Text message.
2223
data_message (Optional[DataMessage]): Data message.
2324
priority (Optional[MessagePriority]): Priority.
2425
sim_number (Optional[int]): SIM card number (1-3), if not set - default SIM will be used.
@@ -60,14 +61,20 @@ def asdict(self) -> t.Dict[str, t.Any]:
6061
Returns:
6162
Dict[str, Any]: A dictionary representation of the message.
6263
"""
64+
65+
def _serialize(value: t.Any) -> t.Any:
66+
if hasattr(value, "asdict"):
67+
return value.asdict()
68+
if isinstance(value, datetime.datetime):
69+
return value.isoformat()
70+
if isinstance(value, enum.Enum):
71+
return value.value
72+
return value
73+
6374
return {
64-
snake_to_camel(field.name): (
65-
getattr(self, field.name).asdict()
66-
if hasattr(getattr(self, field.name), "asdict")
67-
else getattr(self, field.name)
68-
)
69-
for field in dataclasses.fields(self)
70-
if getattr(self, field.name) is not None
75+
snake_to_camel(f.name): _serialize(getattr(self, f.name))
76+
for f in dataclasses.fields(self)
77+
if getattr(self, f.name) is not None
7178
}
7279

7380

android_sms_gateway/http.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ def patch(
133133
def _process_response(self, response: requests.Response) -> dict:
134134
try:
135135
response.raise_for_status()
136+
if response.status_code == 204:
137+
return {}
138+
136139
return response.json()
137140
except requests.exceptions.HTTPError as e:
138141
# Extract error message from response if available
@@ -145,7 +148,9 @@ def _process_response(self, response: requests.Response) -> dict:
145148

146149
# Use the error mapping to create appropriate exception
147150
error_message = str(e) or "HTTP request failed"
148-
raise error_from_status(error_message, response.status_code, error_data)
151+
raise error_from_status(
152+
error_message, response.status_code, error_data
153+
) from e
149154

150155
DEFAULT_CLIENT = RequestsHttpClient
151156
except ImportError:
@@ -176,6 +181,9 @@ def __exit__(self, exc_type, exc_val, exc_tb):
176181
def _process_response(self, response: httpx.Response) -> dict:
177182
try:
178183
response.raise_for_status()
184+
if response.status_code == 204:
185+
return {}
186+
179187
return response.json()
180188
except httpx.HTTPStatusError as e:
181189
# Extract error message from response if available
@@ -188,7 +196,9 @@ def _process_response(self, response: httpx.Response) -> dict:
188196

189197
# Use the error mapping to create appropriate exception
190198
error_message = str(e) or "HTTP request failed"
191-
raise error_from_status(error_message, response.status_code, error_data)
199+
raise error_from_status(
200+
error_message, response.status_code, error_data
201+
) from e
192202

193203
def get(
194204
self, url: str, *, headers: t.Optional[t.Dict[str, str]] = None

tests/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ def test_webhook_create(self, client: APIClient):
7171
def test_webhook_create_invalid_url(self, client: APIClient):
7272
"""
7373
Tests that attempting to create a webhook with an invalid URL raises an
74-
`HTTPError`.
74+
`errors.APIError`.
7575
7676
The test creates a webhook with an invalid URL, and then asserts that an
77-
`HTTPError` is raised.
77+
`errors.APIError` is raised.
7878
7979
:param client: An instance of `APIClient`.
8080
"""

tests/test_error_handling.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
import pytest
21
from unittest.mock import Mock
3-
import requests
4-
import httpx
2+
53
import aiohttp
4+
import httpx
5+
import pytest
6+
import requests
67

8+
from android_sms_gateway.ahttp import AiohttpAsyncHttpClient, HttpxAsyncHttpClient
79
from android_sms_gateway.errors import (
810
APIError,
911
BadRequestError,
10-
UnauthorizedError,
1112
ForbiddenError,
12-
NotFoundError,
13+
GatewayTimeoutError,
1314
InternalServerError,
15+
NotFoundError,
1416
ServiceUnavailableError,
15-
GatewayTimeoutError,
17+
UnauthorizedError,
1618
error_from_status,
1719
)
18-
from android_sms_gateway.http import RequestsHttpClient, HttpxHttpClient
19-
from android_sms_gateway.ahttp import AiohttpAsyncHttpClient, HttpxAsyncHttpClient
20+
from android_sms_gateway.http import HttpxHttpClient, RequestsHttpClient
2021

2122

2223
class TestErrorFromStatus:

0 commit comments

Comments
 (0)