diff --git a/extensions/typescript/src/typescriptServiceClient.ts b/extensions/typescript/src/typescriptServiceClient.ts index 09cb2140286..3fe2dde35fd 100644 --- a/extensions/typescript/src/typescriptServiceClient.ts +++ b/extensions/typescript/src/typescriptServiceClient.ts @@ -656,6 +656,8 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient }).catch((err: any) => { if (!wasCancelled) { this.error(`'${command}' request failed with error.`, err); + const properties = this.parseErrorText(err && err.message, command); + this.logTelemetry('languageServiceErrorResponse', properties); } throw err; }); @@ -667,6 +669,30 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient return result; } + /** + * Given a `errorText` from a tsserver request indicating failure in handling a request, + * prepares a payload for telemetry-logging. + */ + private parseErrorText(errorText: string | undefined, command: string) { + const properties: ObjectMap = Object.create(null); + properties['command'] = command; + if (errorText) { + properties['errorText'] = errorText; + + const errorPrefix = 'Error processing request. '; + if (errorText.startsWith(errorPrefix)) { + const prefixFreeErrorText = errorText.substr(errorPrefix.length); + const newlineIndex = prefixFreeErrorText.indexOf('\n'); + if (newlineIndex >= 0) { + // Newline expected between message and stack. + properties['message'] = prefixFreeErrorText.substring(0, newlineIndex); + properties['stack'] = prefixFreeErrorText.substring(newlineIndex + 1); + } + } + } + return properties; + } + private sendNextRequests(): void { while (this.callbacks.pendingResponses === 0 && this.requestQueue.length > 0) { const item = this.requestQueue.shift();