Skip to content

Commit 5aec74a

Browse files
committed
Treat errors on updateOpen as non-recoverable
Any errors on `updateOpen` will cause the TS Server to become out of sync. This change alerts us to errors that happen in `updateOpen`. We then restart the ts server
1 parent 831c955 commit 5aec74a

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

extensions/typescript-language-features/src/features/bufferSyncSupport.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as Proto from '../protocol';
88
import { ITypeScriptServiceClient } from '../typescriptService';
99
import API from '../utils/api';
1010
import { Delayer } from '../utils/async';
11+
import { nulToken } from '../utils/cancellation';
1112
import { Disposable } from '../utils/dispose';
1213
import * as languageModeIds from '../utils/languageModeIds';
1314
import { ResourceMap } from '../utils/resourceMap';
@@ -142,7 +143,7 @@ class BufferSynchronizer {
142143
case 'close': closedFiles.push(change.args); break;
143144
}
144145
}
145-
this.client.executeWithoutWaitingForResponse('updateOpen', { changedFiles, closedFiles, openFiles });
146+
this.client.execute('updateOpen', { changedFiles, closedFiles, openFiles }, nulToken, { nonRecoverable: true });
146147
this._pending.clear();
147148
}
148149
}

extensions/typescript-language-features/src/typescriptService.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ interface StandardTsServerRequests {
5757
'selectionRange': [Proto.SelectionRangeRequestArgs, Proto.SelectionRangeResponse];
5858
'signatureHelp': [Proto.SignatureHelpRequestArgs, Proto.SignatureHelpResponse];
5959
'typeDefinition': [Proto.FileLocationRequestArgs, Proto.TypeDefinitionResponse];
60+
'updateOpen': [Proto.UpdateOpenRequestArgs, Proto.Response];
6061
}
6162

6263
interface NoResponseTsServerRequests {
6364
'open': [Proto.OpenRequestArgs, null];
64-
'close': [Proto.FileRequestArgs];
65+
'close': [Proto.FileRequestArgs, null];
6566
'change': [Proto.ChangeRequestArgs, null];
66-
'updateOpen': [Proto.UpdateOpenRequestArgs, null];
6767
'compilerOptionsForInferredProjects': [Proto.SetCompilerOptionsForInferredProjectsArgs, null];
6868
'reloadProjects': [null, null];
6969
'configurePlugin': [Proto.ConfigurePluginRequest, Proto.ConfigurePluginResponse];
@@ -76,7 +76,8 @@ interface AsyncTsServerRequests {
7676
export type TypeScriptRequests = StandardTsServerRequests & NoResponseTsServerRequests & AsyncTsServerRequests;
7777

7878
export type ExecConfig = {
79-
lowPriority?: boolean;
79+
readonly lowPriority?: boolean;
80+
readonly nonRecoverable?: boolean;
8081
};
8182

8283
export interface ITypeScriptServiceClient {
@@ -138,4 +139,4 @@ export interface ITypeScriptServiceClient {
138139
* Cancel on going geterr requests and re-queue them after `f` has been evaluated.
139140
*/
140141
interruptGetErr<R>(f: () => R): R;
141-
}
142+
}

extensions/typescript-language-features/src/typescriptServiceClient.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -611,12 +611,18 @@ export default class TypeScriptServiceClient extends Disposable implements IType
611611
}
612612

613613
public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, config?: ExecConfig): Promise<ServerResponse.Response<Proto.Response>> {
614-
return this.executeImpl(command, args, {
614+
const execution = this.executeImpl(command, args, {
615615
isAsync: false,
616616
token,
617617
expectsResult: true,
618618
lowPriority: config ? config.lowPriority : undefined
619619
});
620+
621+
if (config?.nonRecoverable) {
622+
execution.catch(() => this.fatalError(command));
623+
}
624+
625+
return execution;
620626
}
621627

622628
public executeWithoutWaitingForResponse(command: keyof TypeScriptRequests, args: any): void {
@@ -647,6 +653,21 @@ export default class TypeScriptServiceClient extends Disposable implements IType
647653
return this.bufferSyncSupport.interuptGetErr(f);
648654
}
649655

656+
private fatalError(command: string): void {
657+
/* __GDPR__
658+
"fatalError" : {
659+
"${include}": [
660+
"${TypeScriptCommonProperties}",
661+
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
662+
]
663+
}
664+
*/
665+
this.logTelemetry('fatalError', { command });
666+
console.error(`A non-recoverable error occured while executing tsserver command: ${command}`);
667+
668+
this.restartTsServer();
669+
}
670+
650671
private dispatchEvent(event: Proto.Event) {
651672
switch (event.event) {
652673
case 'syntaxDiag':

0 commit comments

Comments
 (0)