Skip to content

Commit bda2159

Browse files
committed
fix(code-index): dispose all scope resources
1 parent f460793 commit bda2159

2 files changed

Lines changed: 29 additions & 7 deletions

File tree

src/services/code-index/__tests__/code-index-scope.spec.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,31 @@ describe("CodeIndexScope", () => {
5959
expect(manager.initialize).toHaveBeenCalledExactlyOnceWith(contextProxy)
6060
})
6161

62-
it("disposes its manager", async () => {
62+
it("disposes its resources", async () => {
6363
const { scope } = createScope()
6464
const codeIndexManager = getManager(scope)
65+
const stateManager = vi.mocked(CodeIndexStateManager).mock.results[0].value
6566
await scope.dispose()
6667
expect(codeIndexManager.dispose).toHaveBeenCalledExactlyOnceWith()
68+
expect(stateManager.dispose).toHaveBeenCalledExactlyOnceWith()
6769
})
6870

69-
it("disposes state when manager disposal rejects", async () => {
71+
it("continues disposing resources when a disposal rejects", async () => {
7072
const { scope } = createScope()
7173
const codeIndexManager = getManager(scope)
7274
const stateManager = vi.mocked(CodeIndexStateManager).mock.results[0].value
7375
const error = new Error("disposal failed")
7476
vi.mocked(codeIndexManager.dispose).mockRejectedValue(error)
7577

76-
await expect(scope.dispose()).rejects.toThrow(error)
78+
let caught: unknown
79+
try {
80+
await scope.dispose()
81+
} catch (error) {
82+
caught = error
83+
}
7784

85+
expect(caught).toBeInstanceOf(AggregateError)
86+
expect((caught as AggregateError).errors).toEqual([error])
7887
expect(codeIndexManager.dispose).toHaveBeenCalledOnce()
7988
expect(stateManager.dispose).toHaveBeenCalledOnce()
8089
})

src/services/code-index/code-index-scope.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import type { ContextProxy } from "../../core/config/ContextProxy"
44
import { CodeIndexManager } from "./manager"
55
import { CodeIndexStateManager } from "./state-manager"
66

7+
type Disposable = {
8+
dispose(): void | Promise<void>
9+
}
10+
711
/** Owns the code-index resources associated with one workspace. */
812
export class CodeIndexScope {
913
public readonly codeIndexManager: CodeIndexManager
@@ -20,10 +24,19 @@ export class CodeIndexScope {
2024
}
2125

2226
public async dispose(): Promise<void> {
23-
try {
24-
await this.codeIndexManager.dispose()
25-
} finally {
26-
this.stateManager.dispose()
27+
const disposables: Disposable[] = [this.codeIndexManager, this.stateManager]
28+
const errors: unknown[] = []
29+
30+
for (const disposable of disposables) {
31+
try {
32+
await disposable.dispose()
33+
} catch (error) {
34+
errors.push(error)
35+
}
36+
}
37+
38+
if (errors.length > 0) {
39+
throw new AggregateError(errors, "Failed to dispose code index scope resources")
2740
}
2841
}
2942
}

0 commit comments

Comments
 (0)