From dd2935b09b95a866ca45acf14697ceb1197a3322 Mon Sep 17 00:00:00 2001 From: kiwina Date: Mon, 2 Jun 2025 13:03:08 +0800 Subject: [PATCH 1/2] fix: auto patch for RooIgnoreController_41 --- src/core/task/Task.ts | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 5683c2d9b2..008b9e25c5 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -977,17 +977,7 @@ export class Task extends EventEmitter { await this.initiateTaskLoop(newUserContent) } - public async abortTask(isAbandoned = false) { - console.log(`[subtasks] aborting task ${this.taskId}.${this.instanceId}`) - - // Will stop any autonomously running promises. - if (isAbandoned) { - this.abandoned = true - } - - this.abort = true - this.emit("taskAborted") - + public dispose(): void { // Stop waiting for child task completion. if (this.pauseInterval) { clearInterval(this.pauseInterval) @@ -1004,10 +994,25 @@ export class Task extends EventEmitter { // If we're not streaming then `abortStream` (which reverts the diff // view changes) won't be called, so we need to revert the changes here. + // This check should ideally be more robust or part of abortStream's logic. if (this.isStreaming && this.diffViewProvider.isEditing) { - await this.diffViewProvider.revertChanges() + this.diffViewProvider.revertChanges().catch(console.error) + } + } + + public async abortTask(isAbandoned = false) { + console.log(`[subtasks] aborting task ${this.taskId}.${this.instanceId}`) + + // Will stop any autonomously running promises. + if (isAbandoned) { + this.abandoned = true } + this.abort = true + this.emit("taskAborted") + + this.dispose() // Call the centralized dispose method + // Save the countdown message in the automatic retry or other content. await this.saveClineMessages() } From f826ade13c401541464c58d07578840b39adfffa Mon Sep 17 00:00:00 2001 From: kiwina Date: Mon, 2 Jun 2025 13:26:33 +0800 Subject: [PATCH 2/2] fix: improve error handling during task disposal and cleanup --- src/core/task/Task.ts | 69 +++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 008b9e25c5..a07097546f 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -985,18 +985,48 @@ export class Task extends EventEmitter { } // Release any terminals associated with this task. - TerminalRegistry.releaseTerminalsForTask(this.taskId) - - this.urlContentFetcher.closeBrowser() - this.browserSession.closeBrowser() - this.rooIgnoreController?.dispose() - this.fileContextTracker.dispose() - - // If we're not streaming then `abortStream` (which reverts the diff - // view changes) won't be called, so we need to revert the changes here. - // This check should ideally be more robust or part of abortStream's logic. - if (this.isStreaming && this.diffViewProvider.isEditing) { - this.diffViewProvider.revertChanges().catch(console.error) + try { + // Release any terminals associated with this task. + TerminalRegistry.releaseTerminalsForTask(this.taskId) + } catch (error) { + console.error("Error releasing terminals:", error) + } + + try { + this.urlContentFetcher.closeBrowser() + } catch (error) { + console.error("Error closing URL content fetcher browser:", error) + } + + try { + this.browserSession.closeBrowser() + } catch (error) { + console.error("Error closing browser session:", error) + } + + try { + if (this.rooIgnoreController) { + this.rooIgnoreController.dispose() + this.rooIgnoreController = undefined + } + } catch (error) { + console.error("Error disposing RooIgnoreController:", error) + // This is the critical one for the leak fix + } + + try { + this.fileContextTracker.dispose() + } catch (error) { + console.error("Error disposing file context tracker:", error) + } + + try { + // If we're not streaming then `abortStream` won't be called + if (this.isStreaming && this.diffViewProvider.isEditing) { + this.diffViewProvider.revertChanges().catch(console.error) + } + } catch (error) { + console.error("Error reverting diff changes:", error) } } @@ -1011,10 +1041,19 @@ export class Task extends EventEmitter { this.abort = true this.emit("taskAborted") - this.dispose() // Call the centralized dispose method - + try { + this.dispose() // Call the centralized dispose method + } catch (error) { + console.error(`Error during task ${this.taskId}.${this.instanceId} disposal:`, error) + // Don't rethrow - we want abort to always succeed + } // Save the countdown message in the automatic retry or other content. - await this.saveClineMessages() + try { + // Save the countdown message in the automatic retry or other content. + await this.saveClineMessages() + } catch (error) { + console.error(`Error saving messages during abort for task ${this.taskId}.${this.instanceId}:`, error) + } } // Used when a sub-task is launched and the parent task is waiting for it to