Skip to content

Commit 0c7043d

Browse files
committed
fix(workflows): reconcile failed abort rollbacks
1 parent 804a892 commit 0c7043d

2 files changed

Lines changed: 47 additions & 14 deletions

File tree

apps/sim/lib/execution/cancel-workflow-execution.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,30 @@ describe('cancelWorkflowExecution', () => {
11491149
expect(mockCancelByExecution).not.toHaveBeenCalled()
11501150
})
11511151

1152+
it('finishes cancellation when an aborted idle-pause rollback fails', async () => {
1153+
const controller = new AbortController()
1154+
mockStagePausedCancellation.mockImplementationOnce(async () => {
1155+
controller.abort()
1156+
return { kind: 'idle' }
1157+
})
1158+
mockClearPausedCancellationIntent.mockRejectedValueOnce(new Error('database unavailable'))
1159+
mockCompletePausedCancellation.mockResolvedValue(true)
1160+
1161+
const response = await cancelAsResponse({
1162+
abortSignal: controller.signal,
1163+
})
1164+
1165+
expect(response.status).toBe(200)
1166+
await expect(response.json()).resolves.toMatchObject({
1167+
success: true,
1168+
pausedCancelled: true,
1169+
reason: 'recorded',
1170+
})
1171+
expect(mockClearPausedCancellationIntent).toHaveBeenCalledWith('ex-1', 'wf-1')
1172+
expect(mockWriteTerminalEvent).toHaveBeenCalledOnce()
1173+
expect(mockCompletePausedCancellation).toHaveBeenCalledWith('ex-1', 'wf-1')
1174+
})
1175+
11521176
it('rolls back an active resume staged while cancellation is aborted', async () => {
11531177
const controller = new AbortController()
11541178
mockStagePausedCancellation.mockImplementationOnce(async () => {

apps/sim/lib/execution/cancel-workflow-execution.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -375,21 +375,30 @@ async function rollbackPausedCancellationAfterAbort(args: {
375375
}): Promise<boolean> {
376376
if (!args.abortSignal?.aborted) return false
377377

378-
if (args.stage.kind === 'active_resume') {
379-
const rolledBack = await PauseResumeManager.rollbackActiveResumeCancellation(
380-
args.executionId,
381-
args.workflowId,
382-
args.stage.target.resumeEntryId
383-
)
384-
if (!rolledBack) {
385-
logger.warn('Aborted cancellation could not be rolled back; completing cancellation', {
386-
executionId: args.executionId,
387-
activeResumeEntryId: args.stage.target.resumeEntryId,
388-
})
389-
return false
378+
try {
379+
if (args.stage.kind === 'active_resume') {
380+
const rolledBack = await PauseResumeManager.rollbackActiveResumeCancellation(
381+
args.executionId,
382+
args.workflowId,
383+
args.stage.target.resumeEntryId
384+
)
385+
if (!rolledBack) {
386+
logger.warn('Aborted cancellation could not be rolled back; completing cancellation', {
387+
executionId: args.executionId,
388+
activeResumeEntryId: args.stage.target.resumeEntryId,
389+
})
390+
return false
391+
}
392+
} else if (args.stage.kind === 'idle') {
393+
await PauseResumeManager.clearPausedCancellationIntent(args.executionId, args.workflowId)
390394
}
391-
} else if (args.stage.kind === 'idle') {
392-
await PauseResumeManager.clearPausedCancellationIntent(args.executionId, args.workflowId)
395+
} catch (error) {
396+
logger.warn('Failed to roll back aborted cancellation; completing cancellation', {
397+
executionId: args.executionId,
398+
stageKind: args.stage.kind,
399+
error: toError(error).message,
400+
})
401+
return false
393402
}
394403

395404
return true

0 commit comments

Comments
 (0)