Skip to content

Commit 787ebd2

Browse files
refactor(workflow): update job failure handling and workflow completion logic to prevent duplicate status traces
1 parent b6f7738 commit 787ebd2

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

apps/worker/src/app/workflow/usecases/run-job/run-job.usecase.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ export class RunJob {
390390
throw caughtError;
391391
} finally {
392392
if (shouldQueueNextJob && !isJobExtendedToSubscriberSchedule) {
393-
await this.tryQueueNextJobs(job, notification);
393+
await this.tryQueueNextJobs(job, notification, !!error);
394394
} else if (!isJobExtendedToSubscriberSchedule) {
395395
// Update workflow run status based on step runs when halting on step failure
396396
await this.workflowRunService.updateDeliveryLifecycle({
@@ -469,8 +469,16 @@ export class RunJob {
469469
* Attempts to queue subsequent jobs in the workflow chain.
470470
* If queueNextJob.execute returns undefined, we stop the workflow.
471471
* Otherwise, we continue trying to queue the next job in the chain.
472+
*
473+
* @param hasCurrentJobError - If true, the current job failed with an error. When the workflow
474+
* ends (no next job), we skip creating the status trace here and let setJobAsFailed handle it
475+
* to avoid duplicate traces and ensure correct error status.
472476
*/
473-
private async tryQueueNextJobs(job: JobEntity, notification?: PartialNotificationEntity | null): Promise<void> {
477+
private async tryQueueNextJobs(
478+
job: JobEntity,
479+
notification?: PartialNotificationEntity | null,
480+
hasCurrentJobError = false
481+
): Promise<void> {
474482
let currentJob: JobEntity | null = job;
475483
let nextJob: JobEntity | null = null;
476484
if (!currentJob) {
@@ -491,16 +499,18 @@ export class RunJob {
491499
});
492500

493501
if (!nextJob) {
494-
// Update workflow run status when there is no next job (workflow complete)
495-
await this.workflowRunService.updateDeliveryLifecycle({
496-
workflowStatus: WorkflowRunStatusEnum.COMPLETED,
497-
notificationId: currentJob._notificationId,
498-
environmentId: currentJob._environmentId,
499-
organizationId: currentJob._organizationId,
500-
_subscriberId: currentJob._subscriberId,
501-
notification,
502-
currentJob: { type: currentJob.type, _id: currentJob._id },
503-
});
502+
if (!hasCurrentJobError) {
503+
// Update workflow run status when there is no next job (workflow complete successfully)
504+
await this.workflowRunService.updateDeliveryLifecycle({
505+
workflowStatus: WorkflowRunStatusEnum.COMPLETED,
506+
notificationId: currentJob._notificationId,
507+
environmentId: currentJob._environmentId,
508+
organizationId: currentJob._organizationId,
509+
_subscriberId: currentJob._subscriberId,
510+
notification,
511+
currentJob: { type: currentJob.type, _id: currentJob._id },
512+
});
513+
}
504514

505515
return;
506516
}
@@ -589,15 +599,15 @@ export class RunJob {
589599
);
590600

591601
const isHaltingWorkflow = shouldHaltOnStepFailure(nextJob) && !this.shouldBackoff(error as Error);
592-
const isLastJobInWorkflow = !jobAfterNext || isHaltingWorkflow;
602+
const isLastJobFailed = !jobAfterNext || isHaltingWorkflow;
593603

594604
await this.setJobAsFailed.execute(
595605
SetJobAsFailedCommand.create({
596606
environmentId: nextJob._environmentId,
597607
jobId: nextJob._id,
598608
organizationId: nextJob._organizationId,
599609
userId: nextJob._userId,
600-
isLastJobInWorkflow,
610+
isLastJobFailed,
601611
}),
602612
error as Error
603613
);

apps/worker/src/app/workflow/usecases/update-job-status/set-job-as-failed.usecase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class SetJobAsFailed {
3535
environmentId: command.environmentId,
3636
organizationId: command.organizationId,
3737
_subscriberId: jobEntity._subscriberId,
38-
workflowStatus: command.isLastJobInWorkflow ? WorkflowRunStatusEnum.COMPLETED : WorkflowRunStatusEnum.PROCESSING,
38+
workflowStatus: command.isLastJobFailed ? WorkflowRunStatusEnum.ERROR : WorkflowRunStatusEnum.PROCESSING,
3939
currentJob: { type: jobEntity.type, _id: jobEntity._id },
4040
});
4141

apps/worker/src/app/workflow/usecases/update-job-status/set-job-as.command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ export class SetJobAsFailedCommand extends SetJobAsCommand {
1111
organizationId: string;
1212

1313
@IsOptional()
14-
isLastJobInWorkflow?: boolean;
14+
isLastJobFailed?: boolean;
1515
}

0 commit comments

Comments
 (0)