Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions changelog.d/unreleased/2687.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
category: fixed
issues:
- 2687
- 2689
- 2690
- 2693
affected:
- src/CodeIndex/Cli/IndexCommandRunner.cs
- tests/CodeIndex.Tests/IndexCommandRunnerTests.cs
---

## English

- **Indexing no longer stalls indefinitely on pathological symbol extraction (#2687, #2689, #2690, #2693)** - `cdidx index` now bounds symbol extraction progress and reports `E013_INDEX_EXTRACTION_STALLED` instead of hanging or misreporting the run as a user interrupt.

## 日本語

- **病的に遅いシンボル抽出で index が無期限に停止しないようになりました (#2687, #2689, #2690, #2693)** - `cdidx index` はシンボル抽出の進捗停止を制限し、ハングしたりユーザー割り込みとして誤報したりせず `E013_INDEX_EXTRACTION_STALLED` を報告します。
33 changes: 33 additions & 0 deletions tests/CodeIndex.Tests/IndexCommandRunnerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,39 @@ public void FormatIndexPhasePath_AppendsPhaseSuffixForJsonLiveness()
Assert.Equal("src/App.cs (references)", message);
}

[Fact]
public void Run_FilesMode_WhenSymbolExtractionStalls_ReportsStallInsteadOfInterrupt()
{
var priorTimeout = IndexCommandRunner.IndexExtractionStallTimeoutForTesting;
IndexCommandRunner.IndexExtractionStallTimeoutForTesting = () => TimeSpan.FromMilliseconds(1);
var projectRoot = CreateTempProject();
try
{
var source = Path.Combine(
GetRepositoryRoot(),
"src",
"CodeIndex",
"Indexer",
"Symbols",
"SymbolExtractor.JavaScriptTypeScriptSupport.cs");
File.Copy(source, Path.Combine(projectRoot, "slow.cs"));

var dbPath = Path.Combine(Path.GetTempPath(), $"cdidx_symbol_timeout_{Guid.NewGuid():N}.db");
var (exitCode, json, stderr) = RunAndCaptureJsonWithStderr([projectRoot, "--files", "slow.cs", "--db", dbPath, "--json", "--force"]);

Assert.Equal(CommandExitCodes.CancelledBySignal, exitCode);
Assert.Equal(CommandErrorCodes.IndexExtractionStalled, json.GetProperty("error_code").GetString());
Assert.Contains("Index extraction made no progress", json.GetProperty("message").GetString());
Assert.DoesNotContain(CommandErrorCodes.Interrupted, stderr);
}
finally
{
IndexCommandRunner.IndexExtractionStallTimeoutForTesting = priorTimeout;
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
}
}

[Fact]
public void GetJsonIndexHeartbeatPath_UsesWorkerPhaseWhenMainThreadIsIdle()
{
Expand Down
Loading