Skip to content

Commit 9c90c48

Browse files
fix(compat): return 400 for a non-integer v0.3 REST historyLength (#1382)
## Problem A v0.3 REST `GetTask` with a non-integer `historyLength` returned 500, because the `ValueError` from `int()` was not handled. ## Fix Raise `InvalidParamsError` instead, with the same message the v1.0 REST transport uses. ## Tests `test_on_get_task_non_integer_history_length` and `test_get_task_v03_non_integer_history_length` fail on main. 2325 passed. Fixes #1381 Co-authored-by: mykytanetipa <mykytanetipa@google.com>
1 parent 0d9dafb commit 9c90c48

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎src/a2a/compat/v0_3/rest_handler.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from a2a.compat.v0_3.request_handler import RequestHandler03
2929
from a2a.server.context import ServerCallContext
3030
from a2a.utils import constants
31+
from a2a.utils.errors import InvalidParamsError
3132
from a2a.utils.telemetry import SpanKind, trace_class
3233
from a2a.utils.version_validator import validate_version
3334

@@ -250,7 +251,14 @@ async def on_get_task(
250251
"""
251252
task_id = request.path_params['id']
252253
history_length_str = request.query_params.get('historyLength')
253-
history_length = int(history_length_str) if history_length_str else None
254+
try:
255+
history_length = (
256+
int(history_length_str) if history_length_str else None
257+
)
258+
except ValueError as e:
259+
raise InvalidParamsError(
260+
message=f'Failed to parse historyLength field: {e}.'
261+
) from e
254262

255263
rpc_req = types_v03.GetTaskRequest(
256264
id='',

‎tests/compat/v0_3/test_rest_handler.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from a2a.server.context import ServerCallContext
1010
from a2a.server.request_handlers.request_handler import RequestHandler
1111
from a2a.types.a2a_pb2 import AgentCard
12+
from a2a.utils.errors import InvalidParamsError
1213

1314

1415
@pytest.fixture
@@ -315,6 +316,19 @@ async def test_on_get_task(rest_handler, mock_request, mock_context):
315316
assert called_req.params.history_length == 5
316317

317318

319+
@pytest.mark.anyio
320+
async def test_on_get_task_non_integer_history_length(
321+
rest_handler, mock_request, mock_context
322+
):
323+
mock_request.path_params = {'id': 'task-1'}
324+
mock_request.query_params = {'historyLength': 'abc'}
325+
326+
with pytest.raises(InvalidParamsError):
327+
await rest_handler.on_get_task(mock_request, mock_context)
328+
329+
rest_handler.handler03.on_get_task.assert_not_called()
330+
331+
318332
@pytest.mark.anyio
319333
async def test_list_push_notifications(
320334
rest_handler, mock_request, mock_context

‎tests/compat/v0_3/test_rest_routes_compat.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ async def test_get_task_v03(
199199
assert expected_response == actual_response
200200

201201

202+
@pytest.mark.anyio
203+
async def test_get_task_v03_non_integer_history_length(
204+
client: AsyncClient, request_handler: MagicMock
205+
) -> None:
206+
response = await client.get('/v1/tasks/test_task_id?historyLength=abc')
207+
208+
assert response.status_code == 400
209+
assert response.json()['error']['status'] == 'INVALID_ARGUMENT'
210+
request_handler.on_get_task.assert_not_called()
211+
212+
202213
@pytest.mark.anyio
203214
async def test_list_tasks_not_in_v03_adapter_routes(
204215
request_handler: RequestHandler,

0 commit comments

Comments
 (0)