From 4697be33b76e72c46790346f2dbebb3ff37e4722 Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Tue, 21 Apr 2026 00:29:46 -0300 Subject: [PATCH] docs(routes): adopt 422 Unprocessable Entity for validation errors (#568) Co-authored-by: Claude Sonnet 4.6 --- CHANGELOG.md | 6 ++++++ routes/player_route.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 688ebd8..87402c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,12 @@ This project uses famous football coaches as release codenames, following an A-Z ### Changed +- `routes/player_route.py`: explicitly document `422 Unprocessable Entity` for + payload validation errors on POST and PUT endpoints — added `responses={422: + ...}` to route decorators (OpenAPI schema) and `Raises:` entries to + docstrings; clarifies the 422 (Pydantic validation failure) vs 400 (semantic + ambiguity) distinction (#568) + ### Fixed ### Removed diff --git a/routes/player_route.py b/routes/player_route.py index dc69344..bc9d3ba 100644 --- a/routes/player_route.py +++ b/routes/player_route.py @@ -45,6 +45,9 @@ status_code=status.HTTP_201_CREATED, summary="Creates a new Player", tags=["Players"], + responses={ + 422: {"description": "Unprocessable Entity - request body validation failed"} + }, ) async def post_async( player_model: Annotated[PlayerRequestModel, Body(...)], @@ -64,6 +67,8 @@ async def post_async( Raises: HTTPException: HTTP 409 Conflict error if the Player already exists. + HTTPException: HTTP 422 Unprocessable Entity if request body fails Pydantic + validation (missing or invalid required fields). """ existing = await player_service.retrieve_by_squad_number_async( async_session, player_model.squad_number @@ -188,6 +193,9 @@ async def get_by_squad_number_async( status_code=status.HTTP_204_NO_CONTENT, summary="Updates an existing Player", tags=["Players"], + responses={ + 422: {"description": "Unprocessable Entity - request body validation failed"} + }, ) async def put_async( squad_number: Annotated[int, Path(..., title=SQUAD_NUMBER_TITLE)], @@ -206,9 +214,12 @@ async def put_async( Raises: HTTPException: HTTP 400 Bad Request if squad_number in the request body does not match the path parameter. The path parameter is the authoritative source - of identity on PUT; a mismatch makes the request ambiguous. + of identity on PUT; a mismatch makes the request semantically ambiguous (not + a validation failure). HTTPException: HTTP 404 Not Found error if the Player with the specified Squad Number does not exist. + HTTPException: HTTP 422 Unprocessable Entity if request body fails Pydantic + validation (missing or invalid required fields). """ if player_model.squad_number != squad_number: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)