diff --git a/aws_lambda_powertools/utilities/idempotency/base.py b/aws_lambda_powertools/utilities/idempotency/base.py index f6a3563c103..bee109ef842 100644 --- a/aws_lambda_powertools/utilities/idempotency/base.py +++ b/aws_lambda_powertools/utilities/idempotency/base.py @@ -167,7 +167,7 @@ def _process_idempotency(self, is_replay: bool): # We give preference to ReturnValuesOnConditionCheckFailure because it is a faster and more cost-effective # way of retrieving the existing record after a failed conditional write operation. record = exc.old_data_record or self._get_idempotency_record() - if is_replay and record is not None and record.status == "INPROGRESS": + if is_replay and record is not None and record.status == STATUS_CONSTANTS["INPROGRESS"]: return self._get_function_response() # If a record is found, handle it for status if record: @@ -296,7 +296,7 @@ def _get_function_response(self): else: try: - serialized_response: dict = self.output_serializer.to_dict(response) if response else None + serialized_response: dict = self.output_serializer.to_dict(response) if response is not None else None self.persistence_store.save_success(data=self.data, result=serialized_response) except Exception as save_exception: raise IdempotencyPersistenceLayerError( diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/redis.py b/aws_lambda_powertools/utilities/idempotency/persistence/redis.py index d1c490ee0f3..9327c33bda7 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/redis.py @@ -332,8 +332,8 @@ def _item_to_data_record(self, idempotency_key: str, item: dict[str, Any]) -> Da idempotency_key=idempotency_key, status=item[self.status_attr], in_progress_expiry_timestamp=in_progress_expiry_timestamp, - response_data=str(item.get(self.data_attr)), - payload_hash=str(item.get(self.validation_key_attr)), + response_data=item.get(self.data_attr, ""), + payload_hash=item.get(self.validation_key_attr, ""), expiry_timestamp=item.get("expiration"), ) diff --git a/tests/functional/idempotency/_redis/test_redis_layer.py b/tests/functional/idempotency/_redis/test_redis_layer.py index c2a0976b0ab..22c3b9a6d83 100644 --- a/tests/functional/idempotency/_redis/test_redis_layer.py +++ b/tests/functional/idempotency/_redis/test_redis_layer.py @@ -330,6 +330,25 @@ def test_item_to_datarecord_conversion(valid_record): assert record.in_progress_expiry_timestamp == item[layer.in_progress_expiry_attr] +def test_item_to_datarecord_conversion_missing_optional_attributes(persistence_store_standalone_redis): + """ + When data_attr or validation_key_attr is missing from Redis, + response_data and payload_hash should be empty string, not the string "None". + Regression test for: https://github.com/aws-powertools/powertools-lambda-python/issues/8090 + """ + idempotency_key = "test-func#abc123" + item = { + persistence_store_standalone_redis.status_attr: "COMPLETED", + persistence_store_standalone_redis.expiry_attr: 9999999999, + # data_attr and validation_key_attr intentionally absent + } + + record = persistence_store_standalone_redis._item_to_data_record(idempotency_key, item) + + assert record.response_data == "" + assert record.payload_hash == "" + + def test_idempotent_function_and_lambda_handler_redis_basic( persistence_store_standalone_redis: RedisCachePersistenceLayer, lambda_context,