From df2b777fde1195de8521cdcaed85925886e35567 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Sun, 6 Jul 2025 03:02:26 +0000 Subject: [PATCH] fix: resolve API failures being misclassified as user cancellations (#5427) - Fixed error handling logic in Task.ts to check abort status before calling abortTask() - Ensures API failures show proper error messages instead of 'API Request Cancelled' - Addresses issue where all API failures on Windows were incorrectly categorized as user cancellations --- src/core/task/Task.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 4f0d32c8c1..f2d9671d0a 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1422,20 +1422,21 @@ export class Task extends EventEmitter { // Cline instance to finish aborting (error is thrown here when // any function in the for loop throws due to this.abort). if (!this.abandoned) { + // Check if this was a user-initiated cancellation BEFORE calling abortTask() + // If this.abort is true, it means the user clicked cancel, so we should + // treat this as "user_cancelled" rather than "streaming_failed" + const wasUserCancelled = this.abort + const cancelReason = wasUserCancelled ? "user_cancelled" : "streaming_failed" + const streamingFailedMessage = wasUserCancelled + ? undefined + : (error.message ?? JSON.stringify(serializeError(error), null, 2)) + // If the stream failed, there's various states the task // could be in (i.e. could have streamed some tools the user // may have executed), so we just resort to replicating a // cancel task. this.abortTask() - // Check if this was a user-initiated cancellation - // If this.abort is true, it means the user clicked cancel, so we should - // treat this as "user_cancelled" rather than "streaming_failed" - const cancelReason = this.abort ? "user_cancelled" : "streaming_failed" - const streamingFailedMessage = this.abort - ? undefined - : (error.message ?? JSON.stringify(serializeError(error), null, 2)) - await abortStream(cancelReason, streamingFailedMessage) const history = await provider?.getTaskWithId(this.taskId) @@ -1716,7 +1717,9 @@ export class Task extends EventEmitter { const contextWindow = modelInfo.contextWindow - const currentProfileId = state?.listApiConfigMeta.find((profile) => profile.name === state?.currentApiConfigName)?.id ?? "default"; + const currentProfileId = + state?.listApiConfigMeta.find((profile) => profile.name === state?.currentApiConfigName)?.id ?? + "default" const truncateResult = await truncateConversationIfNeeded({ messages: this.apiConversationHistory,