in src/task/RetryableTask.ts [48:92]
public trySetValue(child: TaskBase, executor?: TaskOrchestrationExecutor): void {
if (!executor) {
throw new DurableError(
"A framework-internal error was detected: " +
"No executor passed to RetryableTask.trySetValue. " +
"A TaskOrchestrationExecutor is required to schedule new tasks. " +
"If this issue persists, please report it here: " +
"https://github.com/Azure/azure-functions-durable-js/issues"
);
}
// Case 1 - child is a timer task
if (this.isWaitingOnTimer) {
this.isWaitingOnTimer = false;
// If we're out of retry attempts, we can set the output value
// of this task to be that of the last error we encountered
if (this.attemptNumber > this.retryOptions.maxNumberOfAttempts) {
this.setValue(true, this.error);
} else {
// If we still have more attempts available, we re-schedule the
// original task. Since these sub-tasks are not user-managed,
// they are declared as internal tasks.
const rescheduledTask = new NoOpTask();
rescheduledTask.parent = this;
this.children.push(rescheduledTask);
executor.trackOpenTask(rescheduledTask);
}
} // Case 2 - child is the API to retry, and it succeeded
else if (child.stateObj === TaskState.Completed) {
// If we have a successful non-timer task, we accept its result
this.setValue(false, child.result);
} // Case 3 - child is the API to retry, and it failed
else {
// If the sub-task failed, schedule timer to retry again.
// Since these sub-tasks are not user-managed, they are declared as internal tasks.
const rescheduledTask = new NoOpTask();
rescheduledTask.parent = this;
this.children.push(rescheduledTask);
executor.trackOpenTask(rescheduledTask);
this.isWaitingOnTimer = true;
this.error = child.result;
this.attemptNumber++;
}
}