Skip to content

Commit 020a899

Browse files
committed
fix: distinguish API failures from user cancellations
- Add abortReason field to Task class to track cancellation source - Update abortTask method to accept reason parameter (user vs api_failure) - Fix cancellation reason logic to use abortReason instead of abort flag - Update ClineProvider calls to specify user cancellation reason - Resolves issue where API failures were incorrectly reported as user cancellations Fixes #5895
1 parent 38d8edf commit 020a899

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

src/core/task/Task.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ export class Task extends EventEmitter<ClineEvents> {
140140
providerRef: WeakRef<ClineProvider>
141141
private readonly globalStoragePath: string
142142
abort: boolean = false
143+
abortReason: 'user' | 'api_failure' | null = null
143144
didFinishAbortingStream = false
144145
abandoned = false
145146
isInitialized = false
@@ -1074,15 +1075,16 @@ export class Task extends EventEmitter<ClineEvents> {
10741075
}
10751076
}
10761077

1077-
public async abortTask(isAbandoned = false) {
1078-
console.log(`[subtasks] aborting task ${this.taskId}.${this.instanceId}`)
1078+
public async abortTask(isAbandoned = false, reason: 'user' | 'api_failure' = 'user') {
1079+
console.log(`[subtasks] aborting task ${this.taskId}.${this.instanceId} with reason: ${reason}`)
10791080

10801081
// Will stop any autonomously running promises.
10811082
if (isAbandoned) {
10821083
this.abandoned = true
10831084
}
10841085

10851086
this.abort = true
1087+
this.abortReason = reason
10861088
this.emit("taskAborted")
10871089

10881090
try {
@@ -1442,13 +1444,12 @@ export class Task extends EventEmitter<ClineEvents> {
14421444
// could be in (i.e. could have streamed some tools the user
14431445
// may have executed), so we just resort to replicating a
14441446
// cancel task.
1445-
this.abortTask()
1447+
this.abortTask(false, 'api_failure')
14461448

1447-
// Check if this was a user-initiated cancellation
1448-
// If this.abort is true, it means the user clicked cancel, so we should
1449-
// treat this as "user_cancelled" rather than "streaming_failed"
1450-
const cancelReason = this.abort ? "user_cancelled" : "streaming_failed"
1451-
const streamingFailedMessage = this.abort
1449+
// Check if this was a user-initiated cancellation or an API failure
1450+
// Use the abortReason to properly distinguish between user cancellations and API failures
1451+
const cancelReason = this.abortReason === 'user' ? "user_cancelled" : "streaming_failed"
1452+
const streamingFailedMessage = this.abortReason === 'user'
14521453
? undefined
14531454
: (error.message ?? JSON.stringify(serializeError(error), null, 2))
14541455

src/core/webview/ClineProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export class ClineProvider
192192
try {
193193
// Abort the running task and set isAbandoned to true so
194194
// all running promises will exit as well.
195-
await cline.abortTask(true)
195+
await cline.abortTask(true, 'user')
196196
} catch (e) {
197197
this.log(
198198
`[subtasks] encountered error while aborting task ${cline.taskId}.${cline.instanceId}: ${e.message}`,
@@ -974,7 +974,7 @@ export class ClineProvider
974974
const rootTask = cline.rootTask
975975
const parentTask = cline.parentTask
976976

977-
cline.abortTask()
977+
cline.abortTask(false, 'user')
978978

979979
await pWaitFor(
980980
() =>

0 commit comments

Comments
 (0)