diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index f3eb7242c13..38db0f2d757 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -66,7 +66,7 @@ namespace ServerState { * Version reported by currently-running tsserver. */ public tsserverVersion: string | undefined, - public langaugeServiceEnabled: boolean, + public languageServiceEnabled: boolean, ) { } public readonly toCancelOnResourceChange = new Set(); @@ -75,8 +75,8 @@ namespace ServerState { this.tsserverVersion = tsserverVersion; } - updateLangaugeServiceEnabled(enabled: boolean) { - this.langaugeServiceEnabled = enabled; + updateLanguageServiceEnabled(enabled: boolean) { + this.languageServiceEnabled = enabled; } } @@ -84,6 +84,7 @@ namespace ServerState { readonly type = Type.Errored; constructor( public readonly error: Error, + public readonly tsServerLogFile: string | undefined, ) { } } @@ -364,7 +365,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType vscode.window.showErrorMessage(localize('serverExitedWithError', 'TypeScript language server exited with error. Error message is: {0}', err.message || err.name)); } - this.serverState = new ServerState.Errored(err); + this.serverState = new ServerState.Errored(err, handle.tsServerLogFile); this.error('TSServer errored with error.', err); if (handle.tsServerLogFile) { this.error(`TSServer log file: ${handle.tsServerLogFile}`); @@ -580,7 +581,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType if (item === reportIssueItem) { const args = previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError - ? getReportIssueArgsForError(previousState.error) + ? getReportIssueArgsForError(previousState.error, previousState.tsServerLogFile) : undefined; vscode.commands.executeCommand('workbench.action.openIssueReporter', args); } @@ -750,9 +751,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType if (this.serverState.type === ServerState.Type.Running) { this.info('Killing TS Server'); + const logfile = this.serverState.server.tsServerLogFile; this.serverState.server.kill(); if (error instanceof TypeScriptServerError) { - this.serverState = new ServerState.Errored(error); + this.serverState = new ServerState.Errored(error, logfile); } } } @@ -789,7 +791,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType { const body = (event as Proto.ProjectLanguageServiceStateEvent).body!; if (this.serverState.type === ServerState.Type.Running) { - this.serverState.updateLangaugeServiceEnabled(body.languageServiceEnabled); + this.serverState.updateLanguageServiceEnabled(body.languageServiceEnabled); } this._onProjectLanguageServiceStateChanged.fire(body); break; @@ -883,30 +885,60 @@ export default class TypeScriptServiceClient extends Disposable implements IType } } -function getReportIssueArgsForError(error: TypeScriptServerError): { extensionId: string, issueTitle: string, issueBody: string } | undefined { +function getReportIssueArgsForError( + error: TypeScriptServerError, + logPath: string | undefined, +): { extensionId: string, issueTitle: string, issueBody: string } | undefined { if (!error.serverStack || !error.serverMessage) { return undefined; } // Note these strings are intentionally not localized // as we want users to file issues in english + + const sections = [ + `❗️❗️❗️ Please fill in the sections below to help us diagnose the issue ❗️❗️❗️`, + `**TypeScript Version:** ${error.version.apiVersion?.fullVersionString}`, + `**Steps to reproduce crash** + +1. +2. +3.`, + ]; + + if (logPath) { + sections.push(`**TS Server Log** + +❗️ Please review and upload this log file to help us diagnose this crash: + +\`${logPath}\` + +The log file may contain personal data, including full paths and source code from your workspace. You can scrub the log file to remove paths or other personal information. +`); + } else { + + sections.push(`**TS Server Log** + +Server logging disabled. To help us fix crashes like this, please enable logging by setting: + +\`\`\`json +"typescript.tsserver.log": "verbose" +\`\`\` + +After enabling this setting, future crash reports will include the server log.`); + } + + sections.push(`**TS Server Error Stack** + +\`\`\` +${error.serverStack} +\`\`\``); + return { extensionId: 'vscode.typescript-language-features', issueTitle: `TS Server fatal error: ${error.serverMessage}`, - issueBody: `**TypeScript Version:** ${error.version.apiVersion?.fullVersionString} - -**Steps to reproduce crash** - -1. -2. -3. - -**TS Server Error Stack** - -\`\`\` -${error.serverStack} -\`\`\``, + issueBody: sections.join('\n\n') }; }