Skip to content

Bug: exception_handler decorator won't return Response with botocore ClientError #1153

Description

@sthuber90

Expected Behaviour

On botocore ClientError the Lambda function shall return:

{
  "statusCode": 400,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": "{\"statusCode\": 400, \"message\": \"Bad Request\"}",
  "isBase64Encoded": false
}

Current Behaviour

Lambda function raises exception and ends with error, instead of returning HTTP response

Code snippet

import json
import boto3
from botocore.exceptions import ClientError

from aws_lambda_powertools.utilities.data_classes import (
    APIGatewayProxyEventV2,
    event_source,
)
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver, content_types
from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools.event_handler.exceptions import (
    BadRequestError,
    InternalServerError,
    NotFoundError,
)
from aws_lambda_powertools.event_handler.api_gateway import Response

logger = Logger()
app = APIGatewayHttpResolver()
dynamo = boto3.resource("dynamodb")


@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
@event_source(data_class=APIGatewayProxyEventV2)
def lambda_handler(event: APIGatewayProxyEventV2, context: LambdaContext):
    return app.resolve(event, context)

@app.get("/my/path")
def get_hello_universe():
    table = dynamo.Table("non-existent")
    table.get_item(
        Key={
            "pk": "abc",
            "sk": "123",
        },
    )
    return {"message": "hello universe"}
    

@app.exception_handler(ClientError)
def handle_botocore_error(ex: ClientError):
    metadata = {"path": app.current_event.path}
    logger.error(f"Exception: {ex}", extra=metadata)
    # return Response(
    #     status_code=400,
    #     content_type=content_types.APPLICATION_JSON,
    #     body=json.dumps({"statusCode": 400, "message": "Bad request"}),
    # )

    raise BadRequestError("something bad happened")

Possible Solution

No response

Steps to Reproduce

Use the provided code snippet to see that the Lambda will throw an exception instead of returning a 400 "Bad Request" response.

AWS Lambda Powertools for Python version

latest (Layer version 18)

AWS Lambda function runtime

3.9

Packaging format used

Lambda Layers

Debugging logs

START RequestId: 846da9eb-f64a-41e7-90cf-293386069384 Version: $LATEST
{"level":"ERROR","location":"handle_botocore_error:45","message":"Exception: An error occurred (AccessDeniedException) when calling the GetItem operation: User: arn:aws:sts::373270804851:assumed-role/test-role-hg1im76s/test is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:eu-central-1:373270804851:table/non-existent","timestamp":"2022-04-25 17:21:59,753+0000","service":"service_undefined","cold_start":true,"function_name":"test","function_memory_size":"128","function_arn":"arn:aws:lambda:eu-central-1:373270804851:function:test","function_request_id":"846da9eb-f64a-41e7-90cf-293386069384","correlation_id":"id","path":"/my/path","xray_trace_id":"1-6266d8b6-7c8a3e216f62498e0331a61a"}
[ERROR] BadRequestError: something bad happened
Traceback (most recent call last):
  File "/opt/python/aws_lambda_powertools/logging/logger.py", line 354, in decorate
    return lambda_handler(event, context)
  File "/opt/python/aws_lambda_powertools/middleware_factory/factory.py", line 134, in wrapper
    response = middleware()
  File "/opt/python/aws_lambda_powertools/utilities/data_classes/event_source.py", line 39, in event_source
    return handler(data_class(event), context)
  File "/var/task/lambda_function.py", line 28, in lambda_handler
    return app.resolve(event, context)
  File "/opt/python/aws_lambda_powertools/event_handler/api_gateway.py", line 498, in resolve
    return self._resolve().build(self.current_event, self._cors)
  File "/opt/python/aws_lambda_powertools/event_handler/api_gateway.py", line 557, in _resolve
    return self._call_route(route, match_results.groupdict())  # pass fn args
  File "/opt/python/aws_lambda_powertools/event_handler/api_gateway.py", line 613, in _call_route
    response_builder = self._call_exception_handler(exc, route)
  File "/opt/python/aws_lambda_powertools/event_handler/api_gateway.py", line 654, in _call_exception_handler
    return ResponseBuilder(handler(exp), route)
  File "/var/task/lambda_function.py", line 52, in handle_botocore_error
    raise BadRequestError("something bad happened")END RequestId: 846da9eb-f64a-41e7-90cf-293386069384
REPORT RequestId: 846da9eb-f64a-41e7-90cf-293386069384	Duration: 344.21 ms	Billed Duration: 345 ms	Memory Size: 128 MB	Max Memory Used: 67 MB	Init Duration: 630.48 ms

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions