aws-powertools/powertools-lambda-python

Bug: Use appropriate error when passing non string query params

Closed this issue · 6 comments

Expected Behaviour

A correctly raised exception with a descriptive message. For example:

TypeError: Query param value must be a string

Current Behaviour

When using enable_validation=True and declaring integer query params in routes, passing string values results in the following error:

    return {k: v.split(",") for k, v in self.query_string_parameters.items()}
               ^^^^^^^
AttributeError: 'int' object has no attribute 'split'

This is really misleading and forces the developer to dig into Powertools source code to determine what is going on.

Code snippet

#### App Code

app = APIGatewayRestResolver(enabled_validation=True)


@app.get("/todos")
def get_todos(page_num: Annotated[int, Query()] = None):
    pass



#### Test Code

event = {
    # ...
    "queryStringParameters": {"page_num": 5}  # <-- Integer value
}

Possible Solution

It looks like Powertools assumes values to be strings, based on the usage of split(). If so, then we should probably raise a TypeError when encountering a query param value that is not a string prior to automatically splitting.

Steps to Reproduce

See Code Snippet

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.9

Packaging format used

PyPi

Debugging logs

Thanks for opening your first issue here! We'll come back to you as soon as we can.
In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

Hi @aalvrz, thanks for opening this! Just to better understand your scenario, are you getting this error when mocking the event in your local env or on a real event coming from APIGW -> Lambda? I'm asking this because I'm 99% sure that APIGateway will send the querystring as a string parameter, regardless of the value it contains. After splitting the value, we convert it to the corresponding type and perform validation.

In your case, I think it's failing because you're not sending "queryStringParameters": {"page_num": 5} # <-- Integer value as a string; it should be "queryStringParameters": {"page_num": "5"} # <-- Integer value.

Can you please let me know?

@leandrodamascena I am getting this error in my unit tests after enabling enable_validation=True. Previously my query parameter values were integers, but after enabling this feature the error occurs.

I was not aware that APIGW converted the query parameter values to strings. In that case this might not be very important, however I would like to know what is the correct way of defining these values for constructed events in unit tests. Should I always stick to strings?

@leandrodamascena I am getting this error in my unit tests after enabling enable_validation=True. Previously my query parameter values were integers, but after enabling this feature the error occurs.

You're right, this doesn't affect the code when you don't use data validation, because we don't need to validate fields, and therefore, we don't need to normalize headers/query strings. I think we need to add some warning/information in this part of our documentation: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#testing-your-code

I was not aware that APIGW converted the query parameter values to strings. In that case this might not be very important, however I would like to know what is the correct way of defining these values for constructed events in unit tests. Should I always stick to strings?

Yes, please always stick with strings.

Warning

This issue is now closed. Please be mindful that future comments are hard for our team to see.
If you need more assistance, please either reopen the issue, or open a new issue referencing this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

This is now released under 3.21.0 version!