Skip to content

Bug: response hook is not called when idempotent function returns None #5150

Closed
@dreamorosi

Description

@dreamorosi

Expected Behaviour

When working with the Idempotency utility, I am able to specify a response hook that should be run on every idempotent request. This allows me to modify the response before it's returned.

Current Behaviour

Currently the response hook is not called, even on idempotent requests, when the data attribute is None (coerced to "null" in DynamoDB).

Having an idempotent function without return is a valid use case for all those customers who want to discard the response or those who don't have control over the return of a function being made idempotent.

Code snippet

import datetime
import os
import uuid
from typing import Dict

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.idempotency import (
    DynamoDBPersistenceLayer,
    IdempotencyConfig,
    idempotent_function,
)
from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import (
    DataRecord,
)
from aws_lambda_powertools.utilities.typing import LambdaContext

logger = Logger(level="DEBUG")

def my_response_hook(response: Dict, idempotent_data: DataRecord) -> Dict:
    logger.info(f"Idempotent data", extra={"idempotent_data": idempotent_data, "response": response})
    
    # ...

    # Must return the response here
    return response


table = "IdempotencyTable"
dynamodb = DynamoDBPersistenceLayer(table_name=table)
config = IdempotencyConfig(response_hook=my_response_hook)

@idempotent_function(data_keyword_argument="order", config=config, persistence_store=dynamodb)
def process_order(order: dict) -> dict:
    logger.info(f"Processing order id {event.get('order_id')}")

    # return empty response
    return None


def lambda_handler(event: dict, context: LambdaContext):
    config.register_lambda_context(context)  # see Lambda timeouts section
    try:
        return process_order(order=event.get("order"))
    except Exception as err:
        return {"status_code": 400, "error": f"Error processing {str(err)}"}

Possible Solution

No response

Steps to Reproduce

Run the function twice with the following payload:

{"order_id": "123", "order": {"product": "book", "quantity": 1}}

and observe that the log within my_response_hook is never called on subsequent requests, which are idempotent.

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.12

Packaging format used

PyPi

Debugging logs

2024-09-10 18:46:14,454 aws_lambda_powertools.logging.logger [DEBUG] Adding filter in root logger to suppress child logger records to bubble up
2024-09-10 18:46:14,454 aws_lambda_powertools.logging.logger [DEBUG] Marking logger service_undefined as preconfigured
/Users/aamorosi/Codes/idemhook/.venv/lib/python3.12/site-packages/aws_lambda_powertools/utilities/idempotency/base.py:121: UserWarning: Couldn't determine the remaining time left. Did you call register_lambda_context on IdempotencyConfig?
  self.persistence_store.save_inprogress(
2024-09-10 18:46:14,518 aws_lambda_powertools.utilities.idempotency.persistence.base [DEBUG] Saving in progress record for idempotency key: test-func.__main__.process_order#8b950be0cfbb11287739766d35c63f4b
2024-09-10 18:46:14,518 aws_lambda_powertools.utilities.idempotency.persistence.dynamodb [DEBUG] Putting record for idempotency key: test-func.__main__.process_order#8b950be0cfbb11287739766d35c63f4b
{"level":"INFO","location":"process_order:44","message":"Processing order id 123","timestamp":"2024-09-10 18:46:14,530+0200","service":"service_undefined"}
2024-09-10 18:46:14,530 aws_lambda_powertools.utilities.idempotency.persistence.base [DEBUG] Function successfully executed. Saving record to persistence store with idempotency key: test-func.__main__.process_order#8b950be0cfbb11287739766d35c63f4b
2024-09-10 18:46:14,530 aws_lambda_powertools.utilities.idempotency.persistence.dynamodb [DEBUG] Updating record for idempotency key: test-func.__main__.process_order#8b950be0cfbb11287739766d35c63f4b

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingidempotencyIdempotency utility

    Type

    No type

    Projects

    Status

    Shipped

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions