mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-08 12:13:36 +00:00
Fold _error_response back into _handle_error to match OpenAI/Azure convention. Update all call sites and tests accordingly. Made-with: Cursor
82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
from types import SimpleNamespace
|
|
|
|
from nanobot.providers.anthropic_provider import AnthropicProvider
|
|
from nanobot.providers.openai_compat_provider import OpenAICompatProvider
|
|
|
|
|
|
def _fake_response(
|
|
*,
|
|
status_code: int,
|
|
headers: dict[str, str] | None = None,
|
|
text: str = "",
|
|
) -> SimpleNamespace:
|
|
return SimpleNamespace(
|
|
status_code=status_code,
|
|
headers=headers or {},
|
|
text=text,
|
|
)
|
|
|
|
|
|
def test_openai_handle_error_extracts_structured_metadata() -> None:
|
|
class FakeStatusError(Exception):
|
|
pass
|
|
|
|
err = FakeStatusError("boom")
|
|
err.status_code = 409
|
|
err.response = _fake_response(
|
|
status_code=409,
|
|
headers={"retry-after-ms": "250", "x-should-retry": "false"},
|
|
text='{"error":{"type":"rate_limit_exceeded","code":"rate_limit_exceeded"}}',
|
|
)
|
|
err.body = {"error": {"type": "rate_limit_exceeded", "code": "rate_limit_exceeded"}}
|
|
|
|
response = OpenAICompatProvider._handle_error(err)
|
|
|
|
assert response.finish_reason == "error"
|
|
assert response.error_status_code == 409
|
|
assert response.error_type == "rate_limit_exceeded"
|
|
assert response.error_code == "rate_limit_exceeded"
|
|
assert response.error_retry_after_s == 0.25
|
|
assert response.error_should_retry is False
|
|
|
|
|
|
def test_openai_handle_error_marks_timeout_kind() -> None:
|
|
class FakeTimeoutError(Exception):
|
|
pass
|
|
|
|
response = OpenAICompatProvider._handle_error(FakeTimeoutError("timeout"))
|
|
|
|
assert response.finish_reason == "error"
|
|
assert response.error_kind == "timeout"
|
|
|
|
|
|
def test_anthropic_handle_error_extracts_structured_metadata() -> None:
|
|
class FakeStatusError(Exception):
|
|
pass
|
|
|
|
err = FakeStatusError("boom")
|
|
err.status_code = 408
|
|
err.response = _fake_response(
|
|
status_code=408,
|
|
headers={"retry-after": "1.5", "x-should-retry": "true"},
|
|
)
|
|
err.body = {"type": "error", "error": {"type": "rate_limit_error"}}
|
|
|
|
response = AnthropicProvider._handle_error(err)
|
|
|
|
assert response.finish_reason == "error"
|
|
assert response.error_status_code == 408
|
|
assert response.error_type == "rate_limit_error"
|
|
assert response.error_retry_after_s == 1.5
|
|
assert response.error_should_retry is True
|
|
|
|
|
|
def test_anthropic_handle_error_marks_connection_kind() -> None:
|
|
class FakeConnectionError(Exception):
|
|
pass
|
|
|
|
response = AnthropicProvider._handle_error(FakeConnectionError("connection"))
|
|
|
|
assert response.finish_reason == "error"
|
|
assert response.error_kind == "connection"
|