def _handle_for_status(self, event_record: DataRecord) -> Optional[Dict[Any, Any]]: """ Take appropriate action based on event_record's status Parameters ---------- event_record: DataRecord Returns ------- Optional[Dict[Any, Any] Lambda response previously used for this idempotency key, if it has successfully executed already. Raises ------ AlreadyInProgressError A lambda execution is already in progress IdempotencyInconsistentStateError The persistence store reports inconsistent states across different requests. Retryable. """ # This code path will only be triggered if the record becomes expired between the save_inprogress call and here if event_record.status == STATUS_CONSTANTS["EXPIRED"]: raise IdempotencyInconsistentStateError("save_inprogress and get_record return inconsistent results.") if event_record.status == STATUS_CONSTANTS["INPROGRESS"]: raise IdempotencyAlreadyInProgressError( f"Execution already in progress with idempotency key: " f"{self.persistence_store.event_key_jmespath}={event_record.idempotency_key}" ) return event_record.response_json_as_dict()
def _get_idempotency_record(self) -> DataRecord: """ Retrieve the idempotency record from the persistence layer. Raises ---------- IdempotencyInconsistentStateError """ try: event_record = self.persistence_store.get_record(event=self.event, context=self.context) except IdempotencyItemNotFoundError: # This code path will only be triggered if the record is removed between save_inprogress and get_record. logger.debug( "An existing idempotency record was deleted before we could retrieve it. Proceeding with lambda " "handler" ) raise IdempotencyInconsistentStateError("save_inprogress and get_record return inconsistent results.") # Allow this exception to bubble up except IdempotencyValidationError: raise # Wrap remaining unhandled exceptions with IdempotencyPersistenceLayerError to ease exception handling for # clients except Exception as exc: raise IdempotencyPersistenceLayerError("Failed to get record from idempotency store") from exc return event_record