Skip to content

Commit 3a19914

Browse files
committed
fix error handling
1 parent d6485a4 commit 3a19914

3 files changed

Lines changed: 43 additions & 31 deletions

File tree

sdk/src/main/java/software/amazon/lambda/durable/execution/ExecutionManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ private void onCheckpointComplete(List<Operation> newOperations) {
128128
* @return List of child operations for the given operationId
129129
*/
130130
public List<Operation> getChildOperations(String operationId) {
131+
// todo: this is O(n) - consider an improvement if performance becomes an issue
131132
var children = new ArrayList<Operation>();
132133
for (Operation op : operationStorage.values()) {
133134
if (Objects.equals(op.parentId(), operationId)) {

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

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0
33
package software.amazon.lambda.durable.operation;
44

5+
import static software.amazon.lambda.durable.execution.ExecutionManager.isTerminalStatus;
6+
57
import java.nio.charset.StandardCharsets;
68
import java.util.concurrent.CompletableFuture;
79
import java.util.concurrent.ExecutorService;
@@ -203,37 +205,48 @@ public T get() {
203205
}
204206

205207
// throw a general failed exception if a user exception is not reconstructed
206-
switch (subType) {
207-
case WAIT_FOR_CALLBACK: {
208-
var childrenOps = getChildOperations(op.id());
209-
var callbackOp = childrenOps.stream()
210-
.filter(o -> o.type() == OperationType.CALLBACK)
211-
.findFirst()
212-
.orElse(null);
213-
var stepOp = childrenOps.stream()
214-
.filter(o -> o.type() == OperationType.STEP)
215-
.findFirst()
216-
.orElse(null);
217-
if (callbackOp != null) {
218-
switch (callbackOp.status()) {
219-
case FAILED -> throw new CallbackFailedException(callbackOp);
220-
case TIMED_OUT -> throw new CallbackTimeoutException(callbackOp);
221-
default -> throw new ChildContextFailedException(op);
222-
}
223-
}
224-
if (stepOp != null) {
225-
var stepError = stepOp.stepDetails().error();
226-
if (StepInterruptedException.isStepInterruptedException(stepError)) {
227-
throw new CallbackSubmitterException(callbackOp, new StepInterruptedException(stepOp));
228-
} else {
229-
throw new CallbackSubmitterException(callbackOp, new StepFailedException(stepOp));
230-
}
231-
}
208+
return switch (subType) {
209+
case WAIT_FOR_CALLBACK -> handleWaitForCallbackFailure(op);
210+
// todo: handle MAP/PARALLEL
211+
case MAP -> throw new ChildContextFailedException(op);
212+
case PARALLEL -> throw new ChildContextFailedException(op);
213+
case RUN_IN_CHILD_CONTEXT -> throw new ChildContextFailedException(op);
214+
};
215+
}
216+
}
217+
218+
private T handleWaitForCallbackFailure(Operation op) {
219+
var childrenOps = getChildOperations(op.id());
220+
var callbackOp = childrenOps.stream()
221+
.filter(o -> o.type() == OperationType.CALLBACK)
222+
.findFirst()
223+
.orElse(null);
224+
var submitterOp = childrenOps.stream()
225+
.filter(o -> o.type() == OperationType.STEP)
226+
.findFirst()
227+
.orElse(null);
228+
if (callbackOp != null) {
229+
// if callback failed
230+
if (isTerminalStatus(callbackOp.status())) {
231+
switch (callbackOp.status()) {
232+
case FAILED -> throw new CallbackFailedException(callbackOp);
233+
case TIMED_OUT -> throw new CallbackTimeoutException(callbackOp);
234+
}
235+
}
236+
237+
// if submitter failed
238+
if (submitterOp != null
239+
&& isTerminalStatus(submitterOp.status())
240+
&& submitterOp.status() != OperationStatus.SUCCEEDED) {
241+
var stepError = submitterOp.stepDetails().error();
242+
if (StepInterruptedException.isStepInterruptedException(stepError)) {
243+
throw new CallbackSubmitterException(callbackOp, new StepInterruptedException(submitterOp));
244+
} else {
245+
throw new CallbackSubmitterException(callbackOp, new StepFailedException(submitterOp));
232246
}
233-
// todo: add cases for MAP/PARALLEL
234-
default:
235-
throw new ChildContextFailedException(op);
236247
}
237248
}
249+
250+
throw new IllegalStateException("Unknown waitForCallback status");
238251
}
239252
}

sdk/src/test/java/software/amazon/lambda/durable/TestUtils.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ public static DurableExecutionClient createMockClient() {
3535
.callbackId(UUID.randomUUID().toString())
3636
.build());
3737
}
38-
39-
responseOperations.add(opBuilder.build());
4038
} else if (update.action() == OperationAction.SUCCEED) {
4139
opBuilder.status(OperationStatus.SUCCEEDED);
4240
if (update.type() == OperationType.STEP) {

0 commit comments

Comments
 (0)