Skip to content

Commit 8a16b2c

Browse files
Quinn SinclairFullyTyped
authored andcommitted
[Fix][invoke_handler] Fail when invoking a stopped step
Extends invoke_handler to throw error when handling existing step that is already stopped, matching current JS behaviour [1]. [1]https://github.com/aws/aws-durable-execution-sdk-js/blob/716353f1f388f85b7a3c8b02dad4efede2098092/packages/aws-durable-execution-sdk-js/src/handlers/invoke-handler/invoke-handler.ts#L81-L87
1 parent a2a4cc2 commit 8a16b2c

3 files changed

Lines changed: 18 additions & 3 deletions

File tree

src/aws_durable_execution_sdk_python/operation/invoke.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ def invoke_handler(
6161
)
6262
return None # type: ignore
6363

64-
if checkpointed_result.is_failed() or checkpointed_result.is_timed_out():
64+
if (
65+
checkpointed_result.is_failed()
66+
or checkpointed_result.is_timed_out()
67+
or checkpointed_result.is_stopped()
68+
):
6569
# Operation failed, throw the exact same error on replay as the checkpointed failure
6670
checkpointed_result.raise_callable_error()
6771

src/aws_durable_execution_sdk_python/state.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ def is_failed(self) -> bool:
9393

9494
return op.status is OperationStatus.FAILED
9595

96+
def is_stopped(self) -> bool:
97+
"""Return True if the checkpointed operation is STOPPED"""
98+
op = self.operation
99+
if not op:
100+
return False
101+
102+
return op.status is OperationStatus.STOPPED
103+
96104
def is_started(self) -> bool:
97105
"""Return True if the checkpointed operation is STARTED."""
98106
op = self.operation

tests/operation/invoke_test.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ def test_invoke_handler_already_succeeded_no_invoke_details():
109109
assert result is None
110110

111111

112-
def test_invoke_handler_already_failed():
112+
@pytest.mark.parametrize(
113+
"kind", [OperationStatus.FAILED, OperationStatus.STOPPED, OperationStatus.TIMED_OUT]
114+
)
115+
def test_invoke_handler_already_terminated(kind: OperationStatus):
113116
"""Test invoke_handler when operation already failed."""
114117
mock_state = Mock(spec=ExecutionState)
115118
mock_state.durable_execution_arn = "test_arn"
@@ -120,7 +123,7 @@ def test_invoke_handler_already_failed():
120123
operation = Operation(
121124
operation_id="invoke4",
122125
operation_type=OperationType.INVOKE,
123-
status=OperationStatus.FAILED,
126+
status=kind,
124127
invoke_details=InvokeDetails(durable_execution_arn="invoked_arn", error=error),
125128
)
126129
mock_result = CheckpointedResult.create_from_operation(operation)

0 commit comments

Comments
 (0)