Skip to content

Commit 6da33f4

Browse files
committed
fix(bedrock,vertex): add missing 413 and 529 status error handling
The Bedrock and Vertex clients' _make_status_error methods were missing handlers for HTTP 413 (RequestTooLargeError) and 529 (OverloadedError). These were already handled in the main Anthropic/AsyncAnthropic clients (added in #1244), but the Bedrock and Vertex variants fell through to the generic InternalServerError (for 529) or APIStatusError (for 413). This makes error handling consistent across all client variants, so users can catch specific exception types regardless of which provider they use.
1 parent d7c0974 commit 6da33f4

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/anthropic/lib/bedrock/_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ def _make_status_error(
114114
if response.status_code == 409:
115115
return _exceptions.ConflictError(err_msg, response=response, body=body)
116116

117+
if response.status_code == 413:
118+
return _exceptions.RequestTooLargeError(err_msg, response=response, body=body)
119+
117120
if response.status_code == 422:
118121
return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
119122

@@ -123,6 +126,9 @@ def _make_status_error(
123126
if response.status_code == 503:
124127
return _exceptions.ServiceUnavailableError(err_msg, response=response, body=body)
125128

129+
if response.status_code == 529:
130+
return _exceptions.OverloadedError(err_msg, response=response, body=body)
131+
126132
if response.status_code >= 500:
127133
return _exceptions.InternalServerError(err_msg, response=response, body=body)
128134
return APIStatusError(err_msg, response=response, body=body)

src/anthropic/lib/vertex/_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ def _make_status_error(
7070
if response.status_code == 409:
7171
return _exceptions.ConflictError(err_msg, response=response, body=body)
7272

73+
if response.status_code == 413:
74+
return _exceptions.RequestTooLargeError(err_msg, response=response, body=body)
75+
7376
if response.status_code == 422:
7477
return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
7578

@@ -82,6 +85,9 @@ def _make_status_error(
8285
if response.status_code == 504:
8386
return _exceptions.DeadlineExceededError(err_msg, response=response, body=body)
8487

88+
if response.status_code == 529:
89+
return _exceptions.OverloadedError(err_msg, response=response, body=body)
90+
8591
if response.status_code >= 500:
8692
return _exceptions.InternalServerError(err_msg, response=response, body=body)
8793
return APIStatusError(err_msg, response=response, body=body)

tests/lib/test_bedrock.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99
from respx import MockRouter
1010

1111
from anthropic import AnthropicBedrock, AsyncAnthropicBedrock
12+
from anthropic._exceptions import (
13+
BadRequestError,
14+
AuthenticationError,
15+
PermissionDeniedError,
16+
NotFoundError,
17+
ConflictError,
18+
RequestTooLargeError,
19+
UnprocessableEntityError,
20+
RateLimitError,
21+
ServiceUnavailableError,
22+
OverloadedError,
23+
InternalServerError,
24+
)
1225

1326
sync_client = AnthropicBedrock(
1427
aws_region="us-east-1",
@@ -195,3 +208,25 @@ def test_region_infer_from_specified_profile(
195208
client = AnthropicBedrock()
196209

197210
assert client.aws_region == next(profile for profile in profiles if profile["name"] == aws_profile)["region"]
211+
212+
213+
@pytest.mark.parametrize(
214+
"status_code, expected_error",
215+
[
216+
(400, BadRequestError),
217+
(401, AuthenticationError),
218+
(403, PermissionDeniedError),
219+
(404, NotFoundError),
220+
(409, ConflictError),
221+
(413, RequestTooLargeError),
222+
(422, UnprocessableEntityError),
223+
(429, RateLimitError),
224+
(500, InternalServerError),
225+
(503, ServiceUnavailableError),
226+
(529, OverloadedError),
227+
],
228+
)
229+
def test_make_status_error(status_code: int, expected_error: type) -> None:
230+
response = httpx.Response(status_code, request=httpx.Request("GET", "/"))
231+
err = sync_client._make_status_error("msg", body=None, response=response)
232+
assert type(err) is expected_error

tests/lib/test_vertex.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@
99
from respx import MockRouter
1010

1111
from anthropic import AnthropicVertex, AsyncAnthropicVertex
12+
from anthropic._exceptions import (
13+
BadRequestError,
14+
AuthenticationError,
15+
PermissionDeniedError,
16+
NotFoundError,
17+
ConflictError,
18+
RequestTooLargeError,
19+
UnprocessableEntityError,
20+
RateLimitError,
21+
ServiceUnavailableError,
22+
DeadlineExceededError,
23+
OverloadedError,
24+
InternalServerError,
25+
)
1226

1327
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
1428

@@ -276,3 +290,29 @@ def test_env_var_base_url_override(self, monkeypatch: pytest.MonkeyPatch) -> Non
276290
base_url="https://test.googleapis.com/v1",
277291
)
278292
assert str(client.base_url).rstrip("/") == "https://test.googleapis.com/v1"
293+
294+
295+
vertex_client = AnthropicVertex(region="region", project_id="project", access_token="my-access-token")
296+
297+
298+
@pytest.mark.parametrize(
299+
"status_code, expected_error",
300+
[
301+
(400, BadRequestError),
302+
(401, AuthenticationError),
303+
(403, PermissionDeniedError),
304+
(404, NotFoundError),
305+
(409, ConflictError),
306+
(413, RequestTooLargeError),
307+
(422, UnprocessableEntityError),
308+
(429, RateLimitError),
309+
(500, InternalServerError),
310+
(503, ServiceUnavailableError),
311+
(504, DeadlineExceededError),
312+
(529, OverloadedError),
313+
],
314+
)
315+
def test_make_status_error(status_code: int, expected_error: type) -> None:
316+
response = httpx.Response(status_code, request=httpx.Request("GET", "/"))
317+
err = vertex_client._make_status_error("msg", body=None, response=response)
318+
assert type(err) is expected_error

0 commit comments

Comments
 (0)