From d344b9903fbd59cb94164289f906d51326043a22 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 6 May 2026 04:39:55 +0000 Subject: [PATCH 1/2] Prompt after 5 restarts in a session. --- _extension/src/session.ts | 39 +++++++++++++++++++++++++--- _extension/src/telemetryReporting.ts | 11 ++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/_extension/src/session.ts b/_extension/src/session.ts index 6bb76a1cf03..8d47c80b5bf 100644 --- a/_extension/src/session.ts +++ b/_extension/src/session.ts @@ -25,6 +25,8 @@ export class SessionManager implements vscode.Disposable { private traceOutputChannel: vscode.LogOutputChannel; private initializedEventEmitter: vscode.EventEmitter; private telemetryReporter: TelemetryReporter; + private restartCount: number = 0; + private restartPromptShown: boolean = false; constructor( context: vscode.ExtensionContext, @@ -43,12 +45,41 @@ export class SessionManager implements vscode.Disposable { registerCommands(context: vscode.ExtensionContext): void { this.disposables.push(vscode.commands.registerCommand("typescript.native-preview.restart", async () => { this.telemetryReporter.sendTelemetryEvent("command.restartLanguageServer"); - if (await this.currentSession?.tryRestartClient(context)) { - // Language client was able to restart without a full session restart - return; + + // Most of the time we can restart the client without fully restarting the session. + const clientRestarted = await this.currentSession?.tryRestartClient(context); + if (!clientRestarted) { + await this.restart(context); } - await this.restart(context); + this.restartCount++; + if (this.restartCount >= 5 && !this.restartPromptShown) { + this.restartPromptShown = true; + this.telemetryReporter.sendTelemetryEvent("restartExceeded.warningShown"); + const experiencing = await vscode.window.showWarningMessage( + "You've restarted the language server several times. Are you experiencing an issue?", + "Yes", + "No", + ) ?? "Dismiss"; + + this.telemetryReporter.sendTelemetryEvent("restartExceeded.experiencingIssue", { choice: experiencing }); + if (experiencing === "Yes") { + const action = await vscode.window.showWarningMessage( + "Would you like to report the issue or view the server output?", + "Report Issue", + "Show Output Logs", + "Dismiss", + ) ?? "Dismiss"; + + this.telemetryReporter.sendTelemetryEvent("restartExceeded.action", { choice: action }); + if (action === "Report Issue") { + vscode.commands.executeCommand("typescript.native-preview.reportIssue"); + } + else if (action === "Show Output Logs") { + vscode.commands.executeCommand("typescript.native-preview.output.focus"); + } + } + } })); } diff --git a/_extension/src/telemetryReporting.ts b/_extension/src/telemetryReporting.ts index 1fcd165205e..b76d484ac93 100644 --- a/_extension/src/telemetryReporting.ts +++ b/_extension/src/telemetryReporting.ts @@ -15,6 +15,9 @@ export interface TelemetryReporter { sendTelemetryEvent(eventName: "command.disableNativePreview"): void; sendTelemetryEvent(eventName: "command.restartLanguageServer"): void; sendTelemetryEvent(eventName: "command.reportIssue"): void; + sendTelemetryEvent(eventName: "restartExceeded.warningShown"): void; + sendTelemetryEvent(eventName: "restartExceeded.experiencingIssue", data: RestartExceededExperiencingIssue): void; + sendTelemetryEvent(eventName: "restartExceeded.action", data: RestartExceededAction): void; sendTelemetryEvent(eventName: "languageServer.start", data: LSServerStart): void; sendTelemetryErrorEvent(eventName: "languageServer.connectionError", data: LSConnectionError): void; @@ -100,3 +103,11 @@ export type ReportIssue = {}; export type UnexpectedTelemetryPurpose = { telemetryPurpose: string; }; + +export type RestartExceededExperiencingIssue = { + choice: "Yes" | "No" | "Dismiss"; +}; + +export type RestartExceededAction = { + choice: "Report Issue" | "Show Output Logs" | "Dismiss"; +}; From 9dba492eeb2910de674eeae9e8e7a0e56f83e6a5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 May 2026 17:46:18 +0000 Subject: [PATCH 2/2] Format. --- _extension/src/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_extension/src/session.ts b/_extension/src/session.ts index 8d47c80b5bf..1db9398dbf9 100644 --- a/_extension/src/session.ts +++ b/_extension/src/session.ts @@ -45,7 +45,7 @@ export class SessionManager implements vscode.Disposable { registerCommands(context: vscode.ExtensionContext): void { this.disposables.push(vscode.commands.registerCommand("typescript.native-preview.restart", async () => { this.telemetryReporter.sendTelemetryEvent("command.restartLanguageServer"); - + // Most of the time we can restart the client without fully restarting the session. const clientRestarted = await this.currentSession?.tryRestartClient(context); if (!clientRestarted) {