Skip to content

Bug: Open API Validation not validating response serialization when body is Falsy. #5887

@amin-farjadi

Description

@amin-farjadi

Expected Behaviour

When:

  • resolver (of type APIGatewayResolver) has enable_validation=True and,
  • route's function is annotated with a return type X (e.g. a Pydantic model) and,
  • route's function return value is not of type X (and cannot be casted)

Expected:
raise a 422 (HTTPStatus.UNPROCESSABLE_ENTITY) as the result of error in response serialization

Current Behaviour

If function's return value is Falsy, the route is resolved to a 200 OK.

Code snippet

from typing import Literal

from aws_lambda_powertools.event_handler.api_gateway import APIGatewayRestResolver
from pydantic import BaseModel
import pytest

app = APIGatewayRestResolver(enable_validation=True)


class Todo(BaseModel):
    title: str
    status: Literal["Pending", "Done"]


@app.get("/none")
def return_none() -> Todo:
    return None


@app.get("/empty_list")
def return_empty_list() -> Todo:
    return list()


@app.get("/empty_dict")
def return_empty_dict() -> Todo:
    return dict()


@app.get("/empty_string")
def return_empty_string() -> Todo:
    return ""


def lambda_handler(event, context):
    return app.resolve(event, context)


# --- Tests below ---


@pytest.fixture()
def event_factory():
    def _factory(path: str):
        return {
            "httpMethod": "GET",
            "path": path,
        }

    yield _factory


@pytest.mark.parametrize(
    "path, body",
    [
        ("/empty_dict", "{}"),
        ("/empty_list", "[]"),
        ("/none", "null"),
        ("/empty_string", ""),
    ],
    ids=["empty_dict", "empty_list", "none", "empty_string"],
)
def test_unexpected_response_validation(path, body, event_factory):
    """Test to demonstrate cases where a non-OK response is expected from APIGatewayResolver."""
    event = event_factory(path)
    response = lambda_handler(event, None)
    assert response["statusCode"] == 200
    assert response["body"] == body


if __name__ == "__main__":
    pytest.main(["-v", __file__])

Possible Solution

Replace the falsy valuation of the response body in the _handle_response method of the OpenAPIValidationMiddleware class with a more robust class/type comparison.

Steps to Reproduce

  • save snippet above to a file
  • install the following dependencies
    • "aws-lambda-powertools>=3.4.1"
    • "pydantic>=2.10.5"
    • "pytest>=8.3.4"
  • run the file

Powertools for AWS Lambda (Python) version

latest, 3.4.1

AWS Lambda function runtime

3.12

Packaging format used

PyPi

Debugging logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingevent_handlerson-holdThis item is on-hold and will be revisited in the futureopenapi-schema

    Type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions