mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: handle pending ask operations during checkpoint restore
- Add handleWebviewAskResponse call before checkpoint restore to resolve any pending ask promises - This prevents "Current ask promise was ignored" errors when restoring checkpoints - Add comprehensive tests for pending ask scenarios Fixes #8177
This commit is contained in:
parent
513fce3f59
commit
760ef23b4f
2 changed files with 92 additions and 11 deletions
|
|
@ -30,6 +30,8 @@ describe("checkpointRestoreHandler", () => {
|
|||
mockCline.abort = true
|
||||
}),
|
||||
checkpointRestore: vi.fn(),
|
||||
handleWebviewAskResponse: vi.fn(),
|
||||
lastMessageTs: undefined,
|
||||
clineMessages: [
|
||||
{ ts: 1, type: "user", say: "user", text: "First message" },
|
||||
{ ts: 2, type: "assistant", say: "assistant", text: "Response" },
|
||||
|
|
@ -238,5 +240,75 @@ describe("checkpointRestoreHandler", () => {
|
|||
"Error during checkpoint restore: Checkpoint restore failed",
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle pending ask operations before checkpoint restore", async () => {
|
||||
// Simulate a pending ask operation
|
||||
mockCline.lastMessageTs = Date.now()
|
||||
|
||||
await handleCheckpointRestoreOperation({
|
||||
provider: mockProvider,
|
||||
currentCline: mockCline,
|
||||
messageTs: 3,
|
||||
messageIndex: 2,
|
||||
checkpoint: { hash: "abc123" },
|
||||
operation: "delete",
|
||||
})
|
||||
|
||||
// Verify handleWebviewAskResponse was called to resolve pending ask
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith("messageResponse", "", undefined)
|
||||
|
||||
// Verify checkpoint restore was still called
|
||||
expect(mockCline.checkpointRestore).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should handle pending ask operations for edit operations", async () => {
|
||||
// Simulate a pending ask operation
|
||||
mockCline.lastMessageTs = Date.now()
|
||||
|
||||
const editData = {
|
||||
editedContent: "Edited content",
|
||||
images: [],
|
||||
apiConversationHistoryIndex: 2,
|
||||
}
|
||||
|
||||
await handleCheckpointRestoreOperation({
|
||||
provider: mockProvider,
|
||||
currentCline: mockCline,
|
||||
messageTs: 3,
|
||||
messageIndex: 2,
|
||||
checkpoint: { hash: "abc123" },
|
||||
operation: "edit",
|
||||
editData,
|
||||
})
|
||||
|
||||
// Verify handleWebviewAskResponse was called to resolve pending ask
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith("messageResponse", "", undefined)
|
||||
|
||||
// Verify checkpoint restore was still called
|
||||
expect(mockCline.checkpointRestore).toHaveBeenCalled()
|
||||
|
||||
// Verify pending edit operation was set
|
||||
expect(mockProvider.setPendingEditOperation).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should not call handleWebviewAskResponse if no pending ask", async () => {
|
||||
// No pending ask operation (lastMessageTs is undefined)
|
||||
mockCline.lastMessageTs = undefined
|
||||
|
||||
await handleCheckpointRestoreOperation({
|
||||
provider: mockProvider,
|
||||
currentCline: mockCline,
|
||||
messageTs: 3,
|
||||
messageIndex: 2,
|
||||
checkpoint: { hash: "abc123" },
|
||||
operation: "delete",
|
||||
})
|
||||
|
||||
// Verify handleWebviewAskResponse was NOT called
|
||||
expect(mockCline.handleWebviewAskResponse).not.toHaveBeenCalled()
|
||||
|
||||
// Verify checkpoint restore was still called
|
||||
expect(mockCline.checkpointRestore).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,18 +27,27 @@ export async function handleCheckpointRestoreOperation(config: CheckpointRestore
|
|||
const { provider, currentCline, messageTs, checkpoint, operation, editData } = config
|
||||
|
||||
try {
|
||||
// For delete operations, ensure the task is properly aborted to handle any pending ask operations
|
||||
// For both delete and edit operations, we need to handle any pending ask operations
|
||||
// This prevents "Current ask promise was ignored" errors
|
||||
// For edit operations, we don't abort because the checkpoint restore will handle it
|
||||
if (operation === "delete" && currentCline && !currentCline.abort) {
|
||||
currentCline.abortTask()
|
||||
// Wait a bit for the abort to complete
|
||||
await pWaitFor(() => currentCline.abort === true, {
|
||||
timeout: 1000,
|
||||
interval: 50,
|
||||
}).catch(() => {
|
||||
// Continue even if timeout - the abort flag should be set
|
||||
})
|
||||
if (currentCline) {
|
||||
// Handle any pending ask operations by providing a response
|
||||
// This unblocks any waiting ask promises before the checkpoint restore
|
||||
if (currentCline.lastMessageTs) {
|
||||
// Use the public method to set a response for any pending ask
|
||||
currentCline.handleWebviewAskResponse("messageResponse", "", undefined)
|
||||
}
|
||||
|
||||
// For delete operations, abort the task
|
||||
if (operation === "delete" && !currentCline.abort) {
|
||||
currentCline.abortTask()
|
||||
// Wait a bit for the abort to complete
|
||||
await pWaitFor(() => currentCline.abort === true, {
|
||||
timeout: 1000,
|
||||
interval: 50,
|
||||
}).catch(() => {
|
||||
// Continue even if timeout - the abort flag should be set
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// For edit operations, set up pending edit data before restoration
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue