Closed
Description
Expected Behaviour
This may or may not be a bug, but the REST API event handler payload validator does not gracefully handle empty bodies. I would expect an empty body to raise a 4xx (maybe a 422)
Current Behaviour
With the following setup, invoking the POST /todos
endpoint with content-type: application/json
but with an empty body will raise a TypeError
and return a 500 error.
Code snippet
from typing import List, Optional
import requests
from pydantic import BaseModel, Field
from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext
tracer = Tracer()
logger = Logger()
app = APIGatewayRestResolver(enable_validation=True)
class Todo(BaseModel):
userId: int
id_: Optional[int] = Field(alias="id", default=None)
title: str
completed: bool
@app.post("/todos")
def create_todo(todo: Todo) -> str:
response = requests.post("https://jsonplaceholder.typicode.com/todos", json=todo.dict(by_alias=True))
response.raise_for_status()
return response.json()["id"]
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
@tracer.capture_lambda_handler
def lambda_handler(event: dict, context: LambdaContext) -> dict:
return app.resolve(event, context)
Possible Solution
The validation middleware handles a json.JSONDecodeError
exception, but json.loads
will raise a TypeError
if the request body is empty.
We could either:
- Catch the
TypeError
and raise an appropriate response - Check for
None
in_get_body
Steps to Reproduce
Invoke the REST endpoint with an empty body.
Powertools for AWS Lambda (Python) version
latest
AWS Lambda function runtime
3.12
Packaging format used
PyPi
Debugging logs
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Shipped
Activity
leandrodamascena commentedon Jan 25, 2024
Hi @Dilski! Thanks for opening this potential bug.
I'm working to reproduce this error and will update this issue as soon as I have an update.
Dilski commentedon Jan 25, 2024
@leandrodamascena just for extra info, we were doing this with a private API gateway and so tested with test invoke on the console
leandrodamascena commentedon Jan 29, 2024
This was the missing piece of this puzzle! I could not reproduce this either in my local environment or on the Swagger/Public/Private endpoint. However, using the APIGW "Test" on the console I was able to reproduce it.
This is a very specific bug and thanks a lot for catching and reporting this. Testing your APIs thought AWS Console it will send to Lambda the exact string you added in the Headers section, and in this case the string is:
If you see, there is a space before the
application/json
string and it fails in this line. It looks like the solution is to remove the spaces before checking the header, something like thisif not content_type_value or content_type_value.strip().startswith("application/json"):
. While we create a PullRequest and release a version to fix this, you can test using the header with no space between key and value:Content-Type:application/json
.We are planning to release a version on February 8th. Please let me know if it is enough for you to wait until then or need this fix immediately.
Thanks.
github-actions commentedon Jan 29, 2024
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 tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
github-actions commentedon Feb 2, 2024
This is now released under 2.33.0 version!