Skip to content

Implement error node caching for improved TreeView user experience #2706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jun 9, 2025

Update

#2706 (comment)

Overview

This PR implements error node caching functionality to significantly improve user experience when dealing with failed tree nodes in the Azure Databases extension. Previously, when nodes failed due to authentication issues or connectivity problems, every tree refresh would retry the failed operation, causing delays and poor UX when multiple nodes were affected simultaneously.

Implementation

Core Changes

Enhanced BaseCachedBranchDataProvider:

  • Added errorNodeCache Map to store failed node states by parent ID
  • Modified getChildren() to check error cache first, preventing repeated failed operations
  • Added resetNodeErrorState() method to clear error states for retry functionality
  • Enhanced cache cleanup in refresh() and pruneCache() methods
  • Creates user-friendly error messages with retry buttons when operations fail

New Retry Command:

  • Created retryAuthentication command that clears error state and refreshes nodes
  • Smart provider detection automatically determines which branch data provider to use
  • Handles both direct element retry and retry button clicks
  • Registered in command system as azureDatabases.retryAuthentication

Utility Functions:

  • hasRetryNode(): Detects error nodes by checking for IDs ending with '/reconnect'
  • createGenericElementWithContext(): Creates tree elements with custom context values
  • Comprehensive test coverage with 14 test cases

Automatic Benefits for Target Providers

Both target providers automatically inherit the error caching functionality:

  • src/tree/azure-resources-view/cosmosdb/CosmosDBBranchDataProvider.ts
  • src/tree/workspace-view/cosmosdb/CosmosDBWorkspaceBranchDataProvider.ts

No changes were needed to these files since they extend the enhanced BaseCachedBranchDataProvider.

User Experience Improvements

Before:

  • Failed nodes would retry connection attempts on every tree refresh
  • Multiple failing nodes caused cascading delays
  • No clear way to retry specific failed operations

After:

  • Failed nodes show cached error messages instantly on refresh
  • Clear "Click here to retry" button with refresh icon for explicit retry
  • Each node can be retried independently without affecting others
  • Telemetry tracking for cache usage monitoring

Example Usage

When a connection fails due to invalid credentials:

  1. Error node displays: "Error: Authentication failed" + "Click here to retry" button
  2. Subsequent tree refreshes return cached error instantly (no retry attempts)
  3. User clicks retry button → clears error cache → attempts fresh connection
  4. If successful, normal tree structure returns; if failed, error is cached again

Testing

  • 14 comprehensive test cases covering all error caching scenarios
  • Tests for cache management, retry functionality, and edge cases
  • Full TypeScript compilation verification
  • No breaking changes to existing functionality

This implementation follows the exact pattern successfully used in the DocumentDB extension, providing the same user experience improvements while maintaining minimal code changes.

Fixes #2700.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • update.code.visualstudio.com
    • Triggering command: node /home/REDACTED/work/vscode-cosmosdb/vscode-cosmosdb/node_modules/.bin/vscode-test (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits June 9, 2025 09:57
Co-authored-by: tnaum-ms <171359267+tnaum-ms@users.noreply.github.com>
Co-authored-by: tnaum-ms <171359267+tnaum-ms@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] Improvement: Introduce support for "cached" error TreeElements in the TreeView Implement error node caching for improved TreeView user experience Jun 9, 2025
@Copilot Copilot AI requested a review from tnaum-ms June 9, 2025 10:06
Copilot finished work on behalf of tnaum-ms June 9, 2025 10:06
@tnaum-ms
Copy link
Collaborator

I updated the original implementation created by Copilot and simplified it.

While working on it, I had to make contextValue a non-read-only value so that a branch data provider can attach the context of the current branch, so that later, we know, after looking at an element, which branch is the one to be refreshed after a retryOperation call.

Now, error nodes are being cached. In the example below the time-to-error is brief as I just modified my authentication details there, but this will kick-in for every error. This will improve the overall responsiveness of the tree view.

Recording.2025-06-10.132733.mp4

@tnaum-ms tnaum-ms requested a review from Copilot June 10, 2025 11:38
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

Adds error node caching and retry support to tree data providers, improving refresh performance and user experience by preventing repeated failed operations and enabling explicit retries.

  • Introduces errorNodeCache, retry-node creation, and reset logic in BaseCachedBranchDataProvider
  • Defines TreeElementWithRetryChildren interface and merges context values for error/retry elements
  • Implements and registers retryOperation command to clear error state and refresh nodes

Reviewed Changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tree/BaseCachedBranchDataProvider.ts Added error-node cache, retry-node creation, and reset API
src/tree/TreeElementWithRetryChildren.ts New interface for retry-mode support
src/tree/TreeElementWithContextValue.ts Made contextValue mutable to allow dynamic updates
src/commands/retryOperation/retryOperation.ts Implemented retry command logic
src/commands/registerCommands.ts Registered azureDatabases.retryOperation command
Multiple CosmosDB*ResourceItem.ts & Postgres*TreeItem.ts Removed readonly from contextValue for consistency

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@tnaum-ms tnaum-ms marked this pull request as ready for review June 10, 2025 11:48
@tnaum-ms tnaum-ms requested a review from a team as a code owner June 10, 2025 11:48
@tnaum-ms tnaum-ms requested a review from sevoku June 10, 2025 11:48
@tnaum-ms
Copy link
Collaborator

@bk201- Would you have time to review that one for the upcoming release? It helps with the responsiveness of the tree view around error nodes, but in order to make it work, I made the contextValue a non-read-only value everywhere.

@tnaum-ms tnaum-ms requested a review from bk201- July 18, 2025 08:00
@bk201-
Copy link
Contributor

bk201- commented Jul 28, 2025

@tnaum-ms
What a reason making contextValue non read only? For many reasons every public property should be read only or has public getter and private setter (public only in case it is really required). At this point I don't see any reason to make it fully public. No one outside the class can't change this property. If you really want to change it there are constructor and getTreeItem() methods to modify this value.

@tnaum-ms
Copy link
Collaborator

@bk201-
I just saw your comment now. Sorry for the late reply!

I'm integrating our error handling where getChildren in the base data provider already does the job. I'm receiving the items as they are, without calling the constructor myself. Also, at that point, it's not yet a TreeItem... It's here:

// update contextValue, append this.contextValue to each child's contextValue
// This is needed as we need to know the context (which view/provider is showing this element)
children.forEach((child) => {
if (isTreeElementWithContextValue(child)) {
child.contextValue = createContextValue([this.contextValue, child.contextValue]);
}
});

I considered adding extra information to the data provider's context, but that would require changes to every data provider we have.

That’s why I ended up removing the readonly from contextValue... it was the simplest solution with the least amount of work.

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

Error loading sessions

Retrying..

Successfully merging this pull request may close these issues.

Improvement: Introduce support for "cached" error TreeElements in the TreeView
3 participants