diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py index 0c738354fd4..e6d1af01dfc 100644 --- a/aws_lambda_powertools/event_handler/api_gateway.py +++ b/aws_lambda_powertools/event_handler/api_gateway.py @@ -656,7 +656,10 @@ def _lookup_exception_handler(self, exp_type: Type) -> Optional[Callable]: def _call_exception_handler(self, exp: Exception, route: Route) -> Optional[ResponseBuilder]: handler = self._lookup_exception_handler(type(exp)) if handler: - return ResponseBuilder(handler(exp), route) + try: + return ResponseBuilder(handler(exp), route) + except ServiceError as service_error: + exp = service_error if isinstance(exp, ServiceError): return ResponseBuilder( diff --git a/tests/functional/event_handler/test_api_gateway.py b/tests/functional/event_handler/test_api_gateway.py index 3738cd11456..1ca28f869cf 100644 --- a/tests/functional/event_handler/test_api_gateway.py +++ b/tests/functional/event_handler/test_api_gateway.py @@ -1217,6 +1217,29 @@ def handle_not_found(_) -> Response: assert result["statusCode"] == 404 +def test_exception_handler_raises_service_error(json_dump): + # GIVEN an exception handler raises a ServiceError (BadRequestError) + app = ApiGatewayResolver() + + @app.exception_handler(ValueError) + def client_error(ex: ValueError): + raise BadRequestError("Bad request") + + @app.get("/my/path") + def get_lambda() -> Response: + raise ValueError("foo") + + # WHEN calling the event handler + # AND a ValueError is raised + result = app(LOAD_GW_EVENT, {}) + + # THEN call the exception_handler + assert result["statusCode"] == 400 + assert result["headers"]["Content-Type"] == content_types.APPLICATION_JSON + expected = {"statusCode": 400, "message": "Bad request"} + assert result["body"] == json_dump(expected) + + def test_event_source_compatibility(): # GIVEN app = APIGatewayHttpResolver()