Prompt user to report issue after single fatal error on insiders

This commit is contained in:
Matt Bierner 2020-03-04 19:25:09 -08:00
parent 36141fa1f3
commit 81c95f2e5c

View file

@ -108,6 +108,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
private serverState: ServerState.State = ServerState.None;
private lastStart: number;
private numberRestarts: number;
private _isPromptingAfterCrash = false;
private isRestarting: boolean = false;
private hasServerFatallyCrashedTooManyTimes = false;
private readonly loadingIndicator = new ServerInitializingIndicator();
@ -323,12 +324,12 @@ export default class TypeScriptServiceClient extends Disposable implements IType
}
const apiVersion = version.apiVersion || API.defaultVersion;
this.onDidChangeTypeScriptVersion(version);
let mytoken = ++this.token;
const handle = this.typescriptServerSpawner.spawn(version, this.configuration, this.pluginManager, {
onFatalError: (command, err) => this.fatalError(command, err),
});
this.serverState = new ServerState.Running(handle, apiVersion, undefined, true);
this.onDidChangeTypeScriptVersion(version);
this.lastStart = Date.now();
/* __GDPR__
@ -515,14 +516,6 @@ export default class TypeScriptServiceClient extends Disposable implements IType
private serviceExited(restart: boolean): void {
this.loadingIndicator.reset();
enum MessageAction {
reportIssue
}
interface MyMessageItem extends vscode.MessageItem {
id: MessageAction;
}
const previousState = this.serverState;
this.serverState = ServerState.None;
@ -530,19 +523,22 @@ export default class TypeScriptServiceClient extends Disposable implements IType
const diff = Date.now() - this.lastStart;
this.numberRestarts++;
let startService = true;
const reportIssueItem: vscode.MessageItem = {
title: localize('serverDiedReportIssue', 'Report Issue'),
};
let prompt: Thenable<undefined | vscode.MessageItem> | undefined = undefined;
if (this.numberRestarts > 5) {
let prompt: Thenable<MyMessageItem | undefined> | undefined = undefined;
this.numberRestarts = 0;
if (diff < 10 * 1000 /* 10 seconds */) {
this.lastStart = Date.now();
startService = false;
this.hasServerFatallyCrashedTooManyTimes = true;
prompt = vscode.window.showErrorMessage<MyMessageItem>(
prompt = vscode.window.showErrorMessage(
localize('serverDiedAfterStart', 'The TypeScript language service died 5 times right after it got started. The service will not be restarted.'),
{
title: localize('serverDiedReportIssue', 'Report Issue'),
id: MessageAction.reportIssue,
});
reportIssueItem);
/* __GDPR__
"serviceExited" : {
"${include}": [
@ -553,25 +549,32 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this.logTelemetry('serviceExited');
} else if (diff < 60 * 1000 * 5 /* 5 Minutes */) {
this.lastStart = Date.now();
prompt = vscode.window.showWarningMessage<MyMessageItem>(
prompt = vscode.window.showWarningMessage(
localize('serverDied', 'The TypeScript language service died unexpectedly 5 times in the last 5 Minutes.'),
{
title: localize('serverDiedReportIssue', 'Report Issue'),
id: MessageAction.reportIssue
});
reportIssueItem);
}
if (prompt) {
prompt.then(item => {
if (item?.id === MessageAction.reportIssue) {
const args = previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError
? getReportIssueArgsForError(previousState.error)
: undefined;
return vscode.commands.executeCommand('workbench.action.openIssueReporter', args);
}
return undefined;
});
} else if (['vscode-insiders', 'code-oss'].includes(vscode.env.uriScheme)) {
// Prompt after a single restart
if (!this._isPromptingAfterCrash && previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError) {
this.numberRestarts = 0;
this._isPromptingAfterCrash = true;
prompt = vscode.window.showWarningMessage(
localize('serverDiedOnce', 'The TypeScript language service died unexpectedly.'),
reportIssueItem);
}
}
prompt?.then(item => {
this._isPromptingAfterCrash = false;
if (item === reportIssueItem) {
const args = previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError
? getReportIssueArgsForError(previousState.error)
: undefined;
vscode.commands.executeCommand('workbench.action.openIssueReporter', args);
}
});
if (startService) {
this.startService(true);
}