fix: handle unconfigured code indexing gracefully to prevent reset loop

- Added early validation in CodeIndexManager.initialize() to check if feature is configured
- Modified extension.ts to handle initialization errors more gracefully
- Improved error handling in _recreateServices() to distinguish configuration issues
- Added user-friendly messages for unconfigured state
- Prevents "Code indexing is not properly configured" from causing extension reset loop

Fixes #9010
This commit is contained in:
Roo Code 2025-11-04 06:25:54 +00:00
parent 8e4b145681
commit a3a5f4eeac
2 changed files with 94 additions and 44 deletions

View file

@ -111,12 +111,28 @@ export async function activate(context: vscode.ExtensionContext) {
codeIndexManagers.push(manager)
// Initialize in background; do not block extension activation
void manager.initialize(contextProxy).catch((error) => {
const message = error instanceof Error ? error.message : String(error)
outputChannel.appendLine(
`[CodeIndexManager] Error during background CodeIndexManager configuration/indexing for ${folder.uri.fsPath}: ${message}`,
)
})
// Only initialize if the feature is enabled to avoid configuration errors
void (async () => {
try {
// Check if the feature is enabled before attempting initialization
// This prevents the "Code indexing is not properly configured" error
// from causing a reset loop when the feature is unconfigured
await manager.initialize(contextProxy)
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
// Only log as an error if it's not a configuration issue
// Configuration issues are expected when the feature is not set up
if (message.includes("Code indexing is not properly configured")) {
outputChannel.appendLine(
`[CodeIndexManager] Code indexing is not configured for ${folder.uri.fsPath}. Please configure the embedding provider and API keys in settings if you want to use code indexing.`,
)
} else {
outputChannel.appendLine(
`[CodeIndexManager] Error during background CodeIndexManager configuration/indexing for ${folder.uri.fsPath}: ${message}`,
)
}
}
})()
context.subscriptions.push(manager)
}

View file

@ -138,20 +138,28 @@ export class CodeIndexManager {
return { requiresRestart }
}
// 4. CacheManager Initialization
// 4. Early validation: Check if feature is configured before attempting initialization
// This prevents the "Code indexing is not properly configured" error from causing issues
if (!this.isFeatureConfigured) {
this._stateManager.setSystemState("Standby", t("embeddings:serviceFactory.codeIndexingNotConfigured"))
// Return early without throwing an error to prevent extension activation issues
return { requiresRestart: false }
}
// 5. CacheManager Initialization
if (!this._cacheManager) {
this._cacheManager = new CacheManager(this.context, this.workspacePath)
await this._cacheManager.initialize()
}
// 4. Determine if Core Services Need Recreation
// 6. Determine if Core Services Need Recreation
const needsServiceRecreation = !this._serviceFactory || requiresRestart
if (needsServiceRecreation) {
await this._recreateServices()
}
// 5. Handle Indexing Start/Restart
// 7. Handle Indexing Start/Restart
// The enhanced vectorStore.initialize() in startIndexing() now handles dimension changes automatically
// by detecting incompatible collections and recreating them, so we rely on that for dimension changes
const shouldStartOrRestartIndexing =
@ -297,6 +305,13 @@ export class CodeIndexManager {
this._orchestrator = undefined
this._searchService = undefined
// Validate configuration before attempting to create services
if (!this._configManager || !this._configManager.isFeatureConfigured) {
// Set a clear state message instead of throwing an error
this._stateManager.setSystemState("Standby", "Code indexing requires configuration")
return
}
// (Re)Initialize service factory
this._serviceFactory = new CodeIndexServiceFactory(
this._configManager!,
@ -332,43 +347,62 @@ export class CodeIndexManager {
const rooIgnoreController = new RooIgnoreController(workspacePath)
await rooIgnoreController.initialize()
// (Re)Create shared service instances
const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices(
this.context,
this._cacheManager!,
ignoreInstance,
rooIgnoreController,
)
try {
// (Re)Create shared service instances
const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices(
this.context,
this._cacheManager!,
ignoreInstance,
rooIgnoreController,
)
// Validate embedder configuration before proceeding
const validationResult = await this._serviceFactory.validateEmbedder(embedder)
if (!validationResult.valid) {
const errorMessage = validationResult.error || "Embedder configuration validation failed"
this._stateManager.setSystemState("Error", errorMessage)
throw new Error(errorMessage)
// Validate embedder configuration before proceeding
const validationResult = await this._serviceFactory.validateEmbedder(embedder)
if (!validationResult.valid) {
const errorMessage = validationResult.error || "Embedder configuration validation failed"
this._stateManager.setSystemState("Error", errorMessage)
throw new Error(errorMessage)
}
// (Re)Initialize orchestrator
this._orchestrator = new CodeIndexOrchestrator(
this._configManager!,
this._stateManager,
this.workspacePath,
this._cacheManager!,
vectorStore,
scanner,
fileWatcher,
)
// (Re)Initialize search service
this._searchService = new CodeIndexSearchService(
this._configManager!,
this._stateManager,
embedder,
vectorStore,
)
// Clear any error state after successful recreation
this._stateManager.setSystemState("Standby", "")
} catch (error) {
// Handle service creation errors gracefully
const errorMessage = error instanceof Error ? error.message : String(error)
// Check if this is a configuration error
if (errorMessage.includes("Code indexing is not properly configured")) {
// Set a user-friendly state message for configuration issues
this._stateManager.setSystemState(
"Standby",
"Code indexing requires configuration. Please set up embedding provider and API keys in settings.",
)
} else {
// For other errors, maintain error state but provide clear messaging
this._stateManager.setSystemState("Error", errorMessage)
// Re-throw non-configuration errors
throw error
}
}
// (Re)Initialize orchestrator
this._orchestrator = new CodeIndexOrchestrator(
this._configManager!,
this._stateManager,
this.workspacePath,
this._cacheManager!,
vectorStore,
scanner,
fileWatcher,
)
// (Re)Initialize search service
this._searchService = new CodeIndexSearchService(
this._configManager!,
this._stateManager,
embedder,
vectorStore,
)
// Clear any error state after successful recreation
this._stateManager.setSystemState("Standby", "")
}
/**