You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 46fbbc0
Browse filesBrowse the repository at this point in the historyBrowse files
fix: handle unhandled exceptions in LSP server and VS Code extension (#10567)
## Problem
Multiple unhandled exceptions can escape to the VS Code extension host,
causing error telemetry and degraded user experience:
1. **Server crash with no user notification** — When the LSP server
process terminates unexpectedly, the default `LanguageClient` behavior
silently retries and eventually gives up without informing the user.
2. **DocumentSymbol crash** (`"name must not be falsy"`) — When the
TypeSpec compiler returns a document symbol with an empty name (e.g.,
from empty string literal properties or parse error recovery), VS Code's
`DocumentSymbol` constructor rejects it. This throws in the
`vscode-languageclient` protocol converter, which has no extension-level
catch.
3. **Server handler crashes** (`"Cannot read properties of undefined
(reading 'kind')"`) — `getSymNode()` can return `undefined` when a
symbol's `declarations` array is empty, but callers access `.kind`
without null checks. This crashes hover, completion, and signature help
requests.
4. **Extension command exceptions escape** — Commands like
`ShowOpenApi3`, `EmitCode`, and `RestartServer` can throw unhandled
exceptions that propagate through `doOperationWithTelemetry` (which
re-throws after logging telemetry).
## Fix
### VS Code Extension (`packages/typespec-vscode`)
- **Custom `ErrorHandler`** on the `LanguageClient`: Shows a
notification with "Restart Server" button when the server crashes,
instead of silently failing.
- **`onUnhandledException` callback** added to all
`doOperationWithTelemetry` calls: Allows callers to handle exceptions
gracefully (log + show notification) instead of re-throwing to the
extension host. The callback now returns `T` so each caller provides the
correct typed fallback value.
- **All commands covered**: `StartExtension`, `EmitCode`,
`RestartServer`, `InstallGlobalCompilerCli`, `CreateProject`,
`ImportFromOpenApi3`, `ShowOpenApi3`, `ServerPathSettingChanged`,
`StartServer` — every command now has proper exception handling.
- **`recreateLSPClient` wrapped in try-catch**: Catches any unexpected
errors during server startup/restart and shows a user notification.
- **Null guard for `tspLanguageClient`** in `ShowOpenApi3` command:
Prevents `TypeError` when client is undefined.
- **`resolveTypeSpecServer` no longer throws**: Invalid `TspServerPath`
config now logs an error and returns `undefined` instead of throwing.
- **`deactivate()` wrapped in try-catch**: Prevents errors during
extension shutdown from crashing the host.
### Compiler LSP Server (`packages/compiler`)
- **DocumentSymbol empty name fix**: `createDocumentSymbol()` now uses
`"<anonymous>"` fallback when name is empty/falsy.
- **5 `getSymNode()` null check fixes**:
- `serverlib.ts` (hover): `sn.kind` → `sn && sn.kind`
- `type-details.ts`: Guard before `getTypeOrValueForNode()`
- `type-signature.ts`: Guard before `getTypeOrValueForNode()`
- `completion.ts`: Guard before `getTypeForNode()` and `symNode?.kind`
for namespace check
### Telemetry Improvements
- **Added `compilerStartType` property** to
`OperationDetailPropertyName` enum to track how the server was launched
(`node` vs `standalone-tsp-cli`).
- **Compiler resolution telemetry**: Every branch in
`resolveTypeSpecServer` now logs to telemetry — invalid setting type,
local/global/configured resolution, development mode, and the "skipped"
case when no workspace is open.
- **Missing error telemetry filled**: Added
`logOperationDetailTelemetry` calls for error paths in `emit-code.ts`
(LSP client null, empty compile result) and `openapi3-preview.ts` (temp
folder creation failure).
- **`tel.lastStep` annotations**: Added to LSP client null-guard
branches in `EmitCode` and `ShowOpenApi3` for easier troubleshooting.
- **`recreateLSPClient` improved**: Error messages now include client
state and specific failure reason for better diagnostics.
## Testing
- All 17 document symbol tests pass
- All 732 server tests pass (3 pre-existing failures in rename-files
unrelated to this change)
- TypeScript compilation clean (`tsc --noEmit`)
- VS Code extension unit tests pass
---------
Co-authored-by: Copilot <copilot@github.com>
Fix server crashes caused by undefined symbol declarations: add null checks for `getSymNode()` in hover, completion, type-details, and type-signature handlers, and use fallback name for empty DocumentSymbol names
Handle unhandled exceptions in VS Code extension: add custom error handler for server crashes with restart notification, wrap commands with graceful exception handling, and add null guards to prevent extension host errors when LSP client is unavailable
0 commit comments