Skip to content

Commit a4f890d

Browse files
committed
fix: throw IllegalStateException when validation of thread type fail
1 parent 0664612 commit a4f890d

3 files changed

Lines changed: 46 additions & 10 deletions

File tree

sdk-integration-tests/src/test/java/software/amazon/lambda/durable/NestedStepIntegrationTest.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import static org.junit.jupiter.api.Assertions.*;
66

77
import org.junit.jupiter.api.Test;
8+
import software.amazon.lambda.durable.config.StepConfig;
89
import software.amazon.lambda.durable.model.ExecutionStatus;
10+
import software.amazon.lambda.durable.retry.RetryStrategies;
911
import software.amazon.lambda.durable.testing.LocalDurableTestRunner;
1012

1113
/** Tests that nested step calling is properly rejected. */
@@ -16,9 +18,13 @@ void nestedStepCallingThrowsIllegalStateException() {
1618
var runner = LocalDurableTestRunner.create(String.class, (input, context) -> {
1719
// outer-step's supplier calls context.step() which internally calls stepAsync().get()
1820
// The get() is called from the outer step's thread (named "1-step"), triggering the check
19-
var future = context.stepAsync("outer-step", String.class, stepCtx -> {
20-
return context.step("inner-step", String.class, stepCtx2 -> "inner-result");
21-
});
21+
var future = context.stepAsync(
22+
"outer-step",
23+
String.class,
24+
stepCtx -> context.step("inner-step", String.class, stepCtx2 -> "inner-result"),
25+
StepConfig.builder()
26+
.retryStrategy(RetryStrategies.Presets.NO_RETRY)
27+
.build());
2228
return future.get();
2329
});
2430

@@ -38,10 +44,16 @@ void awaitingAsyncStepInsideSyncStepThrowsIllegalStateException() {
3844
var asyncFuture = context.stepAsync("async-step", String.class, stepCtx -> "async-result");
3945

4046
// Sync step tries to await the async step's result inside its supplier
41-
return context.step("sync-step", String.class, stepCtx -> {
42-
// This get() is called from sync-step's thread ("2-step"), which is not allowed
43-
return "combined: " + asyncFuture.get();
44-
});
47+
return context.step(
48+
"sync-step",
49+
String.class,
50+
stepCtx -> {
51+
// This get() is called from sync-step's thread ("2-step"), which is not allowed
52+
return "combined: " + asyncFuture.get();
53+
},
54+
StepConfig.builder()
55+
.retryStrategy(RetryStrategies.Presets.NO_RETRY)
56+
.build());
4557
});
4658

4759
var result = runner.run("test");

sdk/src/main/java/software/amazon/lambda/durable/operation/BaseDurableOperation.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,15 @@ protected List<Operation> getChildOperations() {
191191
/**
192192
* Checks if it's called from a Step.
193193
*
194-
* @throws IllegalDurableOperationException if it's in a step
194+
* @throws IllegalStateException if it's in a step
195195
*/
196196
private void validateCurrentThreadType() {
197197
ThreadType current = getCurrentThreadContext().threadType();
198198
if (current == ThreadType.STEP) {
199199
var message = String.format(
200200
"Nested %s operation is not supported on %s from within a %s execution.",
201201
getType(), getName(), current);
202-
// terminate execution and throw the exception
203-
throw terminateExecutionWithIllegalDurableOperationException(message);
202+
throw new IllegalStateException(message);
204203
}
205204
}
206205

sdk/src/test/java/software/amazon/lambda/durable/operation/SerializableDurableOperationTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,31 @@ public String get() {
113113
verify(executionManager).terminateExecution(any(IllegalDurableOperationException.class));
114114
}
115115

116+
@Test
117+
void waitForOperationCompletionThrowsIllegalStateExceptionWhenCalledFromStepThread() {
118+
when(executionManager.getCurrentThreadContext()).thenReturn(new ThreadContext(CONTEXT_ID, ThreadType.STEP));
119+
120+
SerializableDurableOperation<String> op =
121+
new SerializableDurableOperation<>(OPERATION_IDENTIFIER, RESULT_TYPE, SER_DES, durableContext) {
122+
@Override
123+
protected void start() {
124+
markAlreadyCompleted();
125+
assertThrows(IllegalStateException.class, this::waitForOperationCompletion);
126+
}
127+
128+
@Override
129+
protected void replay(Operation existing) {}
130+
131+
@Override
132+
public String get() {
133+
return RESULT;
134+
}
135+
};
136+
137+
op.execute();
138+
verify(executionManager, never()).terminateExecution(any(IllegalDurableOperationException.class));
139+
}
140+
116141
@Test
117142
void waitForOperationCompletionWhenRunningAndReadyToComplete()
118143
throws InterruptedException, ExecutionException, TimeoutException {

0 commit comments

Comments
 (0)