diff --git a/packages/lsp/lsp-local/src/host.ts b/packages/lsp/lsp-local/src/host.ts index 3a2b9fbd7b..55e13ed307 100644 --- a/packages/lsp/lsp-local/src/host.ts +++ b/packages/lsp/lsp-local/src/host.ts @@ -42,7 +42,10 @@ export async function canonicalizeWorkspace( throw new Error(`workspace root "${workspaceRoot}" cannot be resolved: ${messageOf(error)}`, { cause: error }) } throwIfAborted(signal) - const info = await fs.stat(target, signal) + const info = await fs.stat(target, signal).catch((error: unknown) => { + throwIfAborted(signal) + throw error + }) throwIfAborted(signal) if (info?.type !== 'directory') { throw new Error(`workspace root "${workspaceRoot}" is not a directory`) diff --git a/packages/lsp/lsp-local/tests/host.spec.ts b/packages/lsp/lsp-local/tests/host.spec.ts index cd7ed87e17..3db9deb50a 100644 --- a/packages/lsp/lsp-local/tests/host.spec.ts +++ b/packages/lsp/lsp-local/tests/host.spec.ts @@ -57,11 +57,31 @@ describe('canonicalizeWorkspace', () => { await expect(canonicalizeWorkspace(fs, join(root, 'nope'))).rejects.toThrow(/not a directory/) }) + it('wraps a provider failure while resolving the workspace', async () => { + fs.resolve = async () => { throw 'raw workspace resolve failure' } + await expect(canonicalizeWorkspace(fs, ws)) + .rejects.toThrow(`workspace root "${ws}" cannot be resolved: raw workspace resolve failure`) + }) + it('rejects a non-directory workspace', async () => { const file = join(root, 'file.txt') await writeFile(file, 'x') await expect(canonicalizeWorkspace(fs, file)).rejects.toThrow(/not a directory/) }) + + it('normalizes workspace metadata cancellation and preserves other provider failures', async () => { + const providerFailure = new Error('workspace metadata failed') + fs.stat = async () => { throw providerFailure } + await expect(canonicalizeWorkspace(fs, ws)).rejects.toBe(providerFailure) + + const controller = new AbortController() + fs.stat = async () => { + controller.abort(new Error('workspace metadata cancelled')) + throw providerFailure + } + await expect(canonicalizeWorkspace(fs, ws, controller.signal)) + .rejects.toThrow('workspace metadata cancelled') + }) }) describe('readHostSource', () => {