-
Notifications
You must be signed in to change notification settings - Fork 422
Expand file tree
/
Copy pathtest_error_handlers.py
More file actions
145 lines (113 loc) · 4.12 KB
/
test_error_handlers.py
File metadata and controls
145 lines (113 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""Tests for a2a.utils.error_handlers module."""
from unittest.mock import patch
import pytest
from a2a.types import (
InternalError,
TaskNotFoundError,
)
from a2a.utils.errors import (
InvalidRequestError,
MethodNotFoundError,
)
from a2a.utils.error_handlers import (
A2AErrorToHttpStatus,
A2AErrorToTitle,
A2AErrorToTypeURI,
rest_error_handler,
rest_stream_error_handler,
)
class MockJSONResponse:
def __init__(self, content, status_code, media_type=None):
self.content = content
self.status_code = status_code
self.media_type = media_type
@pytest.mark.asyncio
async def test_rest_error_handler_server_error():
"""Test rest_error_handler with A2AError."""
error = InvalidRequestError(message='Bad request')
@rest_error_handler
async def failing_func():
raise error
with patch('a2a.utils.error_handlers.JSONResponse', MockJSONResponse):
result = await failing_func()
assert isinstance(result, MockJSONResponse)
assert result.status_code == 400
assert result.media_type == 'application/problem+json'
assert result.content == {
'type': 'about:blank',
'title': 'Invalid Request Error',
'status': 400,
'detail': 'Bad request',
}
@pytest.mark.asyncio
async def test_rest_error_handler_with_data_extensions():
"""Test rest_error_handler maps A2AError.data to extension fields."""
error = TaskNotFoundError(message='Task not found')
# Dynamically attach data since __init__ no longer accepts it
error.data = {'taskId': '123', 'retry': False}
@rest_error_handler
async def failing_func():
raise error
with patch('a2a.utils.error_handlers.JSONResponse', MockJSONResponse):
result = await failing_func()
assert isinstance(result, MockJSONResponse)
assert result.status_code == 404
assert result.media_type == 'application/problem+json'
assert result.content == {
'type': 'https://a2a-protocol.org/errors/task-not-found',
'title': 'Task Not Found',
'status': 404,
'detail': 'Task not found',
'taskId': '123',
'retry': False,
}
@pytest.mark.asyncio
async def test_rest_error_handler_unknown_exception():
"""Test rest_error_handler with unknown exception."""
@rest_error_handler
async def failing_func():
raise ValueError('Unexpected error')
with patch('a2a.utils.error_handlers.JSONResponse', MockJSONResponse):
result = await failing_func()
assert isinstance(result, MockJSONResponse)
assert result.status_code == 500
assert result.media_type == 'application/problem+json'
assert result.content == {
'type': 'about:blank',
'title': 'Internal Error',
'status': 500,
'detail': 'Unknown exception',
}
@pytest.mark.asyncio
async def test_rest_stream_error_handler_server_error():
"""Test rest_stream_error_handler with A2AError."""
error = InternalError(message='Internal server error')
@rest_stream_error_handler
async def failing_stream():
raise error
with pytest.raises(InternalError) as exc_info:
await failing_stream()
assert exc_info.value == error
@pytest.mark.asyncio
async def test_rest_stream_error_handler_reraises_exception():
"""Test rest_stream_error_handler reraises other exceptions."""
@rest_stream_error_handler
async def failing_stream():
raise RuntimeError('Stream failed')
with pytest.raises(RuntimeError, match='Stream failed'):
await failing_stream()
def test_a2a_error_mappings():
"""Test A2A error mappings."""
# HTTP Status
assert A2AErrorToHttpStatus[InvalidRequestError] == 400
assert A2AErrorToHttpStatus[MethodNotFoundError] == 404
assert A2AErrorToHttpStatus[TaskNotFoundError] == 404
assert A2AErrorToHttpStatus[InternalError] == 500
# Type URI
assert (
A2AErrorToTypeURI[TaskNotFoundError]
== 'https://a2a-protocol.org/errors/task-not-found'
)
# Title
assert A2AErrorToTitle[TaskNotFoundError] == 'Task Not Found'
assert A2AErrorToTitle[InvalidRequestError] == 'Invalid Request Error'