diff --git a/src/client/activation/node/languageServerProxy.ts b/src/client/activation/node/languageServerProxy.ts index 40a53f002c52..610cc58b2001 100644 --- a/src/client/activation/node/languageServerProxy.ts +++ b/src/client/activation/node/languageServerProxy.ts @@ -126,7 +126,12 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy { // Replace all slashes in the method name so it doesn't get scrubbed by vscode-extension-telemetry. method: telemetryEvent.Properties.method?.replace(/\//g, '.') }; - sendTelemetryEvent(eventName, telemetryEvent.Measurements, formattedProperties); + sendTelemetryEvent( + eventName, + telemetryEvent.Measurements, + formattedProperties, + telemetryEvent.Exception + ); }); } await this.registerTestServices(); diff --git a/src/client/telemetry/index.ts b/src/client/telemetry/index.ts index 434b929f59c6..9c71a5ec6fbc 100644 --- a/src/client/telemetry/index.ts +++ b/src/client/telemetry/index.ts @@ -2,7 +2,6 @@ // Licensed under the MIT License. import type { JSONObject } from '@phosphor/coreutils'; -import * as stackTrace from 'stack-trace'; // tslint:disable-next-line: import-name import TelemetryReporter from 'vscode-extension-telemetry/lib/telemetryReporter'; @@ -118,7 +117,7 @@ export function sendTelemetryEvent

= {}; - let eventNameSent = eventName as string; + const eventNameSent = eventName as string; if (ex) { // When sending telemetry events for exceptions no need to send custom properties. @@ -126,9 +125,8 @@ export function sendTelemetryEvent

0) { - parts.push(frame.getTypeName()); - } - if (typeof frame.getMethodName() === 'string' && frame.getMethodName().length > 0) { - parts.push(frame.getMethodName()); - } - if (typeof frame.getFunctionName() === 'string' && frame.getFunctionName().length > 0) { - if (parts.length !== 2 || parts.join('.') !== frame.getFunctionName()) { - parts.push(frame.getFunctionName()); - } - } - return parts.join('.'); -} - /** * Map all shared properties to their data types. */ diff --git a/src/test/telemetry/index.unit.test.ts b/src/test/telemetry/index.unit.test.ts index 13c8487fb5b7..63bb5e9fef1b 100644 --- a/src/test/telemetry/index.unit.test.ts +++ b/src/test/telemetry/index.unit.test.ts @@ -11,7 +11,6 @@ import { instance, mock, verify, when } from 'ts-mockito'; import { WorkspaceConfiguration } from 'vscode'; import { IWorkspaceService } from '../../client/common/application/types'; import { WorkspaceService } from '../../client/common/application/workspace'; -import { EXTENSION_ROOT_DIR } from '../../client/constants'; import { _resetSharedProperties, clearTelemetryReporter, @@ -30,6 +29,8 @@ suite('Telemetry', () => { public static properties: Record[] = []; public static measures: {}[] = []; public static errorProps: string[] | undefined; + public static exception: Error | undefined; + public static clear() { Reporter.eventName = []; Reporter.properties = []; @@ -45,6 +46,10 @@ suite('Telemetry', () => { this.sendTelemetryEvent(eventName, properties, measures); Reporter.errorProps = errorProps; } + public sendTelemetryException(error: Error, properties?: {}, measures?: {}): void { + this.sendTelemetryEvent('Exception', properties, measures); + Reporter.exception = error; + } } setup(() => { @@ -155,95 +160,22 @@ suite('Telemetry', () => { expect(Reporter.measures).to.deep.equal([measures]); expect(Reporter.properties).to.deep.equal([expectedProperties]); }); - test('Send Error Telemetry', () => { - rewiremock.enable(); - const error = new Error('Boo'); - rewiremock('vscode-extension-telemetry').with({ default: Reporter }); - - const eventName = 'Testing'; - const properties = { hello: 'world', foo: 'bar' }; - const measures = { start: 123, end: 987 }; - - // tslint:disable-next-line:no-any - sendTelemetryEvent(eventName as any, measures, properties as any, error); - - const expectedErrorProperties = { - originalEventName: eventName - }; - - expect(Reporter.eventName).to.deep.equal(['ERROR']); - expect(Reporter.measures).to.deep.equal([measures]); - expect(Reporter.properties[0].stackTrace).to.be.length.greaterThan(1); - delete Reporter.properties[0].stackTrace; - expect(Reporter.properties).to.deep.equal([expectedErrorProperties]); - expect(Reporter.errorProps).to.deep.equal([]); - }); - test('Send Error Telemetry with stack trace', () => { + test('Send Exception Telemetry', () => { rewiremock.enable(); const error = new Error('Boo'); - const root = EXTENSION_ROOT_DIR.replace(/\\/g, '/'); - error.stack = [ - 'Error: Boo', - `at Context.test (${root}/src/test/telemetry/index.unit.test.ts:50:23)`, - `at callFn (${root}/node_modules/mocha/lib/runnable.js:372:21)`, - `at Test.Runnable.run (${root}/node_modules/mocha/lib/runnable.js:364:7)`, - `at Runner.runTest (${root}/node_modules/mocha/lib/runner.js:455:10)`, - `at ${root}/node_modules/mocha/lib/runner.js:573:12`, - `at next (${root}/node_modules/mocha/lib/runner.js:369:14)`, - `at ${root}/node_modules/mocha/lib/runner.js:379:7`, - `at next (${root}/node_modules/mocha/lib/runner.js:303:14)`, - `at ${root}/node_modules/mocha/lib/runner.js:342:7`, - `at done (${root}/node_modules/mocha/lib/runnable.js:319:5)`, - `at callFn (${root}/node_modules/mocha/lib/runnable.js:395:7)`, - `at Hook.Runnable.run (${root}/node_modules/mocha/lib/runnable.js:364:7)`, - `at next (${root}/node_modules/mocha/lib/runner.js:317:10)`, - `at Immediate. (${root}/node_modules/mocha/lib/runner.js:347:5)`, - 'at runCallback (timers.js:789:20)', - 'at tryOnImmediate (timers.js:751:5)', - 'at processImmediate [as _immediateCallback] (timers.js:722:5)' - ].join('\n\t'); rewiremock('vscode-extension-telemetry').with({ default: Reporter }); const eventName = 'Testing'; const properties = { hello: 'world', foo: 'bar' }; - const measures = { start: 123, end: 987 }; // tslint:disable-next-line:no-any - sendTelemetryEvent(eventName as any, measures, properties as any, error); + sendTelemetryEvent(eventName as any, {}, properties as any, error); const expectedErrorProperties = { originalEventName: eventName }; - const stackTrace = Reporter.properties[0].stackTrace; - delete Reporter.properties[0].stackTrace; - - expect(Reporter.eventName).to.deep.equal(['ERROR']); - expect(Reporter.measures).to.deep.equal([measures]); expect(Reporter.properties).to.deep.equal([expectedErrorProperties]); - expect(stackTrace).to.be.length.greaterThan(1); - expect(Reporter.errorProps).to.deep.equal([]); - - const expectedStack = [ - `at Context.test ${root}/src/test/telemetry/index.unit.test.ts:50:23`, - `at callFn ${root}/node_modules/mocha/lib/runnable.js:372:21`, - `at Test.Runnable.run ${root}/node_modules/mocha/lib/runnable.js:364:7`, - `at Runner.runTest ${root}/node_modules/mocha/lib/runner.js:455:10`, - `at ${root}/node_modules/mocha/lib/runner.js:573:12`, - `at next ${root}/node_modules/mocha/lib/runner.js:369:14`, - `at ${root}/node_modules/mocha/lib/runner.js:379:7`, - `at next ${root}/node_modules/mocha/lib/runner.js:303:14`, - `at ${root}/node_modules/mocha/lib/runner.js:342:7`, - `at done ${root}/node_modules/mocha/lib/runnable.js:319:5`, - `at callFn ${root}/node_modules/mocha/lib/runnable.js:395:7`, - `at Hook.Runnable.run ${root}/node_modules/mocha/lib/runnable.js:364:7`, - `at next ${root}/node_modules/mocha/lib/runner.js:317:10`, - `at Immediate ${root}/node_modules/mocha/lib/runner.js:347:5`, - 'at runCallback timers.js:789:20', - 'at tryOnImmediate timers.js:751:5', - 'at processImmediate [as _immediateCallback] timers.js:722:5' - ].join('\n\t'); - - expect(stackTrace).to.be.equal(expectedStack); + expect(Reporter.exception).to.deep.equal(error); }); });