Skip to content

Conversation

bryanchen-d
Copy link
Contributor

Add timeout in findFiles and findTextInFiles tool so they won't hang the chat.

@bryanchen-d bryanchen-d requested a review from roblourens October 3, 2025 23:30
const timeoutInMs = 10_000;
let results = await Promise.race([
this.searchAndCollectResults(options.input.query, isRegExp, patterns, maxResults, token),
new Promise<never>((_, reject) => setTimeout(() => reject(new Error("Timeout in searching text in files")), timeoutInMs))]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check whether any helpers in async.ts could be reused here- timeout, raceCancellation, etc. If not that's fine, it's pretty simple.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There areraceTimeout, timeout utilities, but they just resolve to undefined when time's up, while in this case I think we want to throw an error similar to the cancellation case. Do you think we should make a new utility for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, it's fine

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is timeout(ms).then(() => Promise.reject(new Error("...")) cleaner?

@bryanchen-d bryanchen-d self-assigned this Oct 6, 2025
@bryanchen-d bryanchen-d force-pushed the brchen/timeout-in-searching branch from 9dec97e to e1d6814 Compare October 6, 2025 18:10
@bryanchen-d bryanchen-d marked this pull request as ready for review October 6, 2025 18:16
@Copilot Copilot AI review requested due to automatic review settings October 6, 2025 18:16
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds timeout functionality to the findFiles and findTextInFiles tools to prevent them from hanging chat operations. The changes implement a 10-second timeout for both search operations and prompt rendering to improve user experience.

Key changes:

  • Added timeout wrapper using raceTimeout and raceCancellation utilities
  • Applied timeout to both file search operations and prompt rendering phases
  • Added consistent error handling when timeouts occur

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/extension/tools/node/findTextInFilesTool.tsx Added timeout logic to text search operations and prompt rendering with proper error handling
src/extension/tools/node/findFilesTool.tsx Added timeout logic to file search operations and prompt rendering with consistent error messaging

const timeoutInMs = 10_000;
const results = await raceTimeout(
raceCancellation(
Promise.resolve(this.searchService.findFiles(pattern, undefined, token)),
Copy link
Preview

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Promise.resolve() wrapper is unnecessary here. The findFiles method likely already returns a Promise, so this adds unnecessary complexity.

Suggested change
Promise.resolve(this.searchService.findFiles(pattern, undefined, token)),
this.searchService.findFiles(pattern, undefined, token),

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the findFiles returns a Thenable<> which doesn't fit the required Promise<> type, and fails compilation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would make sense for the search service to return a Promise instead (this comes from our extension API but our searchService could do the Promise.resolve. You can do that if it makes things cleaner, you don't have to

@vs-code-engineering vs-code-engineering bot added this to the October 2025 milestone Oct 6, 2025
token);
const results: vscode.TextSearchResult2[] = [];
for await (const item of searchResult.results) {
await new Promise(r => setTimeout(r, 5000)); // yield to allow cancellation to be processed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this? We need to wait 5s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, this shouldn't be checked in, I was using it to validate the timeout case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants