Skip to content

fix(event_handler): serialize pydantic/dataclasses in exception handler #3455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

heitorlessa
Copy link
Contributor

@heitorlessa heitorlessa commented Dec 5, 2023

Issue number: #3451

Summary

This PR changes Powertools JSON Encoder to always serialize pydantic v1/v2 and dataclasses. This addresses an issue for the new data validation feature in Event Handler, where customers might return a Pydantic model as a response in the exception handler.

Changes

Please provide a summary of what's being changed

User experience

Please share what the user experience looks like before and after this change

from typing import List

import requests
from pydantic import BaseModel, Field

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response, content_types
from aws_lambda_powertools.utilities.typing import LambdaContext

tracer = Tracer()
logger = Logger()
app = APIGatewayRestResolver(enable_validation=True, debug=True)

class ErrorModel(BaseModel):
    status_code:int
    message: str

@app.exception_handler(ValueError)
def handle_invalid_limit_qs(ex: ValueError) -> Response[ErrorModel]:  # receives exception raised
    metadata = {"path": app.current_event.path, "query_strings": app.current_event.query_string_parameters}
    logger.error(f"Malformed request: {ex}", extra=metadata)

    return Response(
        status_code=400,
        content_type=content_types.APPLICATION_JSON,
        body=ErrorModel(
            status_code=400,
            message="Invalid data"
        ),
    )


class Todo(BaseModel):
    userId: int
    id_: int = Field(alias="id")
    title: str
    completed: bool


@app.get("/todos")
def get_todos() -> Response[List[Todo]]:
    todo = requests.get("https://jsonplaceholder.typicode.com/todos")
    todo.raise_for_status()

	return todo


def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)

Checklist

If your change doesn't seem to apply, please leave them unchecked.

Is this a breaking change?

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@pull-request-size pull-request-size bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Dec 5, 2023
@heitorlessa heitorlessa linked an issue Dec 5, 2023 that may be closed by this pull request
@pull-request-size pull-request-size bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Dec 5, 2023
@boring-cyborg boring-cyborg bot added the internal Maintenance changes label Dec 5, 2023
@heitorlessa heitorlessa marked this pull request as ready for review December 5, 2023 17:31
@heitorlessa heitorlessa requested a review from a team December 5, 2023 17:31
Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link

sonarqubecloud bot commented Dec 6, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
3.1% 3.1% Duplication

@codecov-commenter
Copy link

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (99aef19) 95.41% compared to head (901c4d5) 95.42%.
Report is 1 commits behind head on develop.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #3455   +/-   ##
========================================
  Coverage    95.41%   95.42%           
========================================
  Files          209      209           
  Lines         9648     9664   +16     
  Branches      1770     1773    +3     
========================================
+ Hits          9206     9222   +16     
  Misses         329      329           
  Partials       113      113           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@heitorlessa heitorlessa merged commit 05dd82b into aws-powertools:develop Dec 6, 2023
@heitorlessa heitorlessa deleted the feat/openapi-exception branch December 6, 2023 09:53
@heitorlessa heitorlessa removed the internal Maintenance changes label Dec 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commons event_handlers size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: Error handler fails to parse pydantic models
3 participants