fix: improve Ollama CPU indexing error handling and timeouts

- Increased Ollama embedding timeout from 60s to 180s for CPU processing
- Increased validation timeout from 30s to 60s for CPU processing
- Increased batch retry count from 3 to 5 attempts
- Increased initial retry delay from 500ms to 2000ms
- Improved error handling logic to distinguish between connection errors and slow processing
- Changed partial failure threshold from 10% to 50% to account for slow CPU processing
- Added warnings instead of errors for moderate failure rates

Fixes #7178
This commit is contained in:
Roo Code 2025-08-18 12:25:12 +00:00
parent a8aea14078
commit 6ee4470925
3 changed files with 48 additions and 30 deletions

View file

@ -17,8 +17,8 @@ export const MAX_FILE_SIZE_BYTES = 1 * 1024 * 1024 // 1MB
/**Directory Scanner */
export const MAX_LIST_FILES_LIMIT_CODE_INDEX = 50_000
export const BATCH_SEGMENT_THRESHOLD = 60 // Number of code segments to batch for embeddings/upserts
export const MAX_BATCH_RETRIES = 3
export const INITIAL_RETRY_DELAY_MS = 500
export const MAX_BATCH_RETRIES = 5 // Increased from 3 to handle slow Ollama CPU processing
export const INITIAL_RETRY_DELAY_MS = 2000 // Increased from 500ms to give Ollama more time between retries
export const PARSING_CONCURRENCY = 10
export const MAX_PENDING_BATCHES = 20 // Maximum number of batches to accumulate before waiting

View file

@ -8,8 +8,9 @@ import { TelemetryService } from "@roo-code/telemetry"
import { TelemetryEventName } from "@roo-code/types"
// Timeout constants for Ollama API requests
const OLLAMA_EMBEDDING_TIMEOUT_MS = 60000 // 60 seconds for embedding requests
const OLLAMA_VALIDATION_TIMEOUT_MS = 30000 // 30 seconds for validation requests
// Increased timeouts to handle slow CPU processing
const OLLAMA_EMBEDDING_TIMEOUT_MS = 180000 // 180 seconds (3 minutes) for embedding requests - increased for CPU processing
const OLLAMA_VALIDATION_TIMEOUT_MS = 60000 // 60 seconds for validation requests - increased for CPU processing
/**
* Implements the IEmbedder interface using a local Ollama instance.

View file

@ -165,39 +165,56 @@ export class CodeIndexOrchestrator {
const { stats } = result
// Check if any blocks were actually indexed successfully
// If no blocks were indexed but blocks were found, it means all batches failed
if (cumulativeBlocksIndexed === 0 && cumulativeBlocksFoundSoFar > 0) {
if (batchErrors.length > 0) {
// Use the first batch error as it's likely representative of the main issue
const firstError = batchErrors[0]
// Only consider it a failure if:
// 1. We found blocks to index AND
// 2. None were successfully indexed AND
// 3. There were actual batch errors (not just slow processing)
if (cumulativeBlocksIndexed === 0 && cumulativeBlocksFoundSoFar > 0 && batchErrors.length > 0) {
// Check if the errors are connection-related (Ollama not running)
const firstError = batchErrors[0]
const isConnectionError =
firstError.message.includes("Ollama service is not running") ||
firstError.message.includes("ECONNREFUSED") ||
firstError.message.includes("fetch failed")
if (isConnectionError) {
// This is a real connection error - Ollama is not accessible
throw new Error(`Indexing failed: ${firstError.message}`)
} else {
// Other types of errors - report as indexing failure
throw new Error(t("embeddings:orchestrator.indexingFailedNoBlocks"))
}
}
// Check for partial failures - if a significant portion of blocks failed
const failureRate = (cumulativeBlocksFoundSoFar - cumulativeBlocksIndexed) / cumulativeBlocksFoundSoFar
if (batchErrors.length > 0 && failureRate > 0.1) {
// More than 10% of blocks failed to index
const firstError = batchErrors[0]
throw new Error(
`Indexing partially failed: Only ${cumulativeBlocksIndexed} of ${cumulativeBlocksFoundSoFar} blocks were indexed. ${firstError.message}`,
// Check for partial failures - but only if we have a significant failure rate
// AND actual errors were reported (not just slow processing)
if (cumulativeBlocksFoundSoFar > 0 && batchErrors.length > 0) {
const failureRate = (cumulativeBlocksFoundSoFar - cumulativeBlocksIndexed) / cumulativeBlocksFoundSoFar
// Only report partial failure if more than 50% failed (not 10%)
// This accounts for slow Ollama processing where some batches might timeout
// but the service is actually working
if (failureRate > 0.5) {
const firstError = batchErrors[0]
throw new Error(
`Indexing partially failed: Only ${cumulativeBlocksIndexed} of ${cumulativeBlocksFoundSoFar} blocks were indexed. ${firstError.message}`,
)
} else if (failureRate > 0.1) {
// Log a warning for moderate failure rates but don't fail the entire process
console.warn(
`[CodeIndexOrchestrator] Some blocks failed to index (${cumulativeBlocksIndexed}/${cumulativeBlocksFoundSoFar} succeeded). This may be due to slow processing.`,
)
}
}
// Final check: If we found blocks but indexed absolutely none and no errors were reported,
// this might indicate the process was interrupted or there's a silent failure
if (cumulativeBlocksFoundSoFar > 0 && cumulativeBlocksIndexed === 0 && batchErrors.length === 0) {
console.warn(
`[CodeIndexOrchestrator] No blocks were indexed despite finding ${cumulativeBlocksFoundSoFar} blocks. The indexing may still be in progress or was interrupted.`,
)
}
// CRITICAL: If there were ANY batch errors and NO blocks were successfully indexed,
// this is a complete failure regardless of the failure rate calculation
if (batchErrors.length > 0 && cumulativeBlocksIndexed === 0) {
const firstError = batchErrors[0]
throw new Error(`Indexing failed completely: ${firstError.message}`)
}
// Final sanity check: If we found blocks but indexed none and somehow no errors were reported,
// this is still a failure
if (cumulativeBlocksFoundSoFar > 0 && cumulativeBlocksIndexed === 0) {
throw new Error(t("embeddings:orchestrator.indexingFailedCritical"))
// Don't throw an error here - let the process continue
// The file watcher will handle subsequent updates
}
await this._startWatcher()