Skip to content

Commit d03d355

Browse files
committed
Add telemetry as argument to showAndLogExceptionWithTelemetry
1 parent 959728d commit d03d355

26 files changed

Lines changed: 100 additions & 23 deletions

File tree

extensions/ql-vscode/src/common/vscode/commands.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,20 @@ import { redactableError } from "../../pure/errors";
1414
import { UserCancellationException } from "./progress";
1515
import { telemetryListener } from "./telemetry";
1616
import { showAndLogExceptionWithTelemetry } from "./logging";
17+
import { AppTelemetry } from "../telemetry";
1718

1819
/**
1920
* Create a command manager for VSCode, wrapping registerCommandWithErrorHandling
2021
* and vscode.executeCommand.
2122
*/
2223
export function createVSCodeCommandManager<
2324
Commands extends Record<string, CommandFunction>,
24-
>(logger?: NotificationLogger): CommandManager<Commands> {
25+
>(
26+
logger?: NotificationLogger,
27+
telemetry?: AppTelemetry,
28+
): CommandManager<Commands> {
2529
return new CommandManager((commandId, task) => {
26-
return registerCommandWithErrorHandling(commandId, task, logger);
30+
return registerCommandWithErrorHandling(commandId, task, logger, telemetry);
2731
}, wrapExecuteCommand);
2832
}
2933

@@ -34,11 +38,13 @@ export function createVSCodeCommandManager<
3438
* @param task The task to run. It is passed directly to `commands.registerCommand`. Any
3539
* arguments to the command handler are passed on to the task.
3640
* @param logger The logger to use for error reporting.
41+
* @param telemetry The telemetry listener to use for error reporting.
3742
*/
3843
export function registerCommandWithErrorHandling(
3944
commandId: string,
4045
task: (...args: any[]) => Promise<any>,
4146
logger: NotificationLogger = extLogger,
47+
telemetry: AppTelemetry | undefined = telemetryListener,
4248
): Disposable {
4349
return commands.registerCommand(commandId, async (...args: any[]) => {
4450
const startTime = Date.now();
@@ -64,7 +70,7 @@ export function registerCommandWithErrorHandling(
6470
const fullMessage = errorStack
6571
? `${errorMessage.fullMessage}\n${errorStack}`
6672
: errorMessage.fullMessage;
67-
void showAndLogExceptionWithTelemetry(logger, errorMessage, {
73+
void showAndLogExceptionWithTelemetry(logger, telemetry, errorMessage, {
6874
fullMessage,
6975
extraTelemetryProperties: {
7076
command: commandId,

extensions/ql-vscode/src/common/vscode/external-files.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from "../../pure/helpers-pure";
1010
import { extLogger } from "../logging";
1111
import { showAndLogExceptionWithTelemetry } from "./logging";
12+
import { telemetryListener } from "./telemetry";
1213

1314
export async function tryOpenExternalFile(
1415
commandManager: AppCommandManager,
@@ -36,6 +37,7 @@ the file in the file explorer and dragging it into the workspace.`,
3637
} catch (e) {
3738
void showAndLogExceptionWithTelemetry(
3839
extLogger,
40+
telemetryListener,
3941
redactableError(
4042
asError(e),
4143
)`Failed to reveal file in OS: ${getErrorMessage(e)}`,
@@ -45,6 +47,7 @@ the file in the file explorer and dragging it into the workspace.`,
4547
} else {
4648
void showAndLogExceptionWithTelemetry(
4749
extLogger,
50+
telemetryListener,
4851
redactableError(asError(e))`Could not open file ${fileLocation}`,
4952
{
5053
fullMessage: `${getErrorMessage(e)}\n${getErrorStack(e)}`,

extensions/ql-vscode/src/common/vscode/logging.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
ShowAndLogOptions,
55
} from "../logging";
66
import { RedactableError } from "../../pure/errors";
7-
import { telemetryListener } from "./telemetry";
7+
import { AppTelemetry } from "../telemetry";
88

99
interface ShowAndLogExceptionOptions extends ShowAndLogOptions {
1010
/** Custom properties to include in the telemetry report. */
@@ -15,16 +15,18 @@ interface ShowAndLogExceptionOptions extends ShowAndLogOptions {
1515
* Show an error message, log it to the console, and emit redacted information as telemetry
1616
*
1717
* @param logger The logger that will receive the message.
18+
* @param telemetry The telemetry instance to use for reporting.
1819
* @param error The error to show. Only redacted information will be included in the telemetry.
1920
* @param options See individual fields on `ShowAndLogExceptionOptions` type.
2021
*
2122
* @return A promise that resolves to the selected item or undefined when being dismissed.
2223
*/
2324
export async function showAndLogExceptionWithTelemetry(
2425
logger: NotificationLogger,
26+
telemetry: AppTelemetry | undefined,
2527
error: RedactableError,
2628
options: ShowAndLogExceptionOptions = {},
2729
): Promise<void> {
28-
telemetryListener?.sendError(error, options.extraTelemetryProperties);
30+
telemetry?.sendError(error, options.extraTelemetryProperties);
2931
return showAndLogErrorMessage(logger, error.fullMessage, options);
3032
}

extensions/ql-vscode/src/compare/compare-view.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ export class CompareView extends AbstractWebview<
152152
case "unhandledError":
153153
void showAndLogExceptionWithTelemetry(
154154
extLogger,
155+
telemetryListener,
155156
redactableError(
156157
msg.error,
157158
)`Unhandled error in result comparison view: ${msg.error.message}`,

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
276276
} catch (err) {
277277
void showAndLogExceptionWithTelemetry(
278278
this.app.logger,
279+
this.app.telemetry,
279280
redactableError(
280281
asError(err),
281282
)`Failed to load external API usages: ${getErrorMessage(err)}`,
@@ -342,6 +343,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
342343
} catch (e: unknown) {
343344
void showAndLogExceptionWithTelemetry(
344345
this.app.logger,
346+
this.app.telemetry,
345347
redactableError(
346348
asError(e),
347349
)`Failed to generate flow model: ${getErrorMessage(e)}`,
@@ -476,6 +478,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
476478
if (e instanceof RequestError && e.status === 429) {
477479
void showAndLogExceptionWithTelemetry(
478480
this.app.logger,
481+
this.app.telemetry,
479482
redactableError(e)`Rate limit hit, please try again soon.`,
480483
);
481484
return null;

extensions/ql-vscode/src/data-extensions-editor/external-api-usage-query.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { fetchExternalApiQueries } from "./queries";
1414
import { QueryResultType } from "../pure/new-messages";
1515
import { join } from "path";
1616
import { redactableError } from "../pure/errors";
17+
import { telemetryListener } from "../common/vscode/telemetry";
1718

1819
export type RunQueryOptions = {
1920
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
@@ -42,6 +43,7 @@ export async function runQuery({
4243
if (!isQueryLanguage(databaseItem.language)) {
4344
void showAndLogExceptionWithTelemetry(
4445
extLogger,
46+
telemetryListener,
4547
redactableError`Unsupported database language ${databaseItem.language}`,
4648
);
4749
return;
@@ -51,6 +53,7 @@ export async function runQuery({
5153
if (!query) {
5254
void showAndLogExceptionWithTelemetry(
5355
extLogger,
56+
telemetryListener,
5457
redactableError`No external API usage query found for language ${databaseItem.language}`,
5558
);
5659
return;
@@ -107,6 +110,7 @@ export async function runQuery({
107110
if (completedQuery.resultType !== QueryResultType.SUCCESS) {
108111
void showAndLogExceptionWithTelemetry(
109112
extLogger,
113+
telemetryListener,
110114
redactableError`External API usage query failed: ${
111115
completedQuery.message ?? "No message"
112116
}`,
@@ -130,6 +134,7 @@ export async function readQueryResults({
130134
if (bqrsInfo["result-sets"].length !== 1) {
131135
void showAndLogExceptionWithTelemetry(
132136
extLogger,
137+
telemetryListener,
133138
redactableError`Expected exactly one result set, got ${bqrsInfo["result-sets"].length}`,
134139
);
135140
return undefined;

extensions/ql-vscode/src/data-extensions-editor/generate-flow-model.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { file } from "tmp-promise";
1818
import { writeFile } from "fs-extra";
1919
import { dump } from "js-yaml";
2020
import { qlpackOfDatabase } from "../language-support";
21+
import { telemetryListener } from "../common/vscode/telemetry";
2122

2223
type FlowModelOptions = {
2324
cliServer: CodeQLCliServer;
@@ -82,6 +83,7 @@ async function getModeledMethodsFromFlow(
8283
if (queryPath === undefined) {
8384
void showAndLogExceptionWithTelemetry(
8485
extLogger,
86+
telemetryListener,
8587
redactableError`Failed to find ${type} query`,
8688
);
8789
return [];
@@ -117,6 +119,7 @@ async function getModeledMethodsFromFlow(
117119
if (queryResult.resultType !== QueryResultType.SUCCESS) {
118120
void showAndLogExceptionWithTelemetry(
119121
extLogger,
122+
telemetryListener,
120123
redactableError`Failed to run ${basename(queryPath)} query: ${
121124
queryResult.message ?? "No message"
122125
}`,
@@ -130,6 +133,7 @@ async function getModeledMethodsFromFlow(
130133
if (bqrsInfo["result-sets"].length !== 1) {
131134
void showAndLogExceptionWithTelemetry(
132135
extLogger,
136+
telemetryListener,
133137
redactableError`Expected exactly one result set, got ${
134138
bqrsInfo["result-sets"].length
135139
} for ${basename(queryPath)}`,

extensions/ql-vscode/src/databases/local-databases-ui.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ export class DatabaseUI extends DisposableObject {
280280
} catch (e) {
281281
void showAndLogExceptionWithTelemetry(
282282
this.app.logger,
283+
this.app.telemetry,
283284
redactableError(
284285
asError(e),
285286
)`Failed to choose and set database: ${getErrorMessage(e)}`,
@@ -420,6 +421,7 @@ export class DatabaseUI extends DisposableObject {
420421
} catch (e) {
421422
void showAndLogExceptionWithTelemetry(
422423
this.app.logger,
424+
this.app.telemetry,
423425
redactableError(
424426
asError(e),
425427
)`Failed to delete orphaned database: ${getErrorMessage(e)}`,
@@ -449,6 +451,7 @@ export class DatabaseUI extends DisposableObject {
449451
} catch (e: unknown) {
450452
void showAndLogExceptionWithTelemetry(
451453
this.app.logger,
454+
this.app.telemetry,
452455
redactableError(
453456
asError(e),
454457
)`Failed to choose and set database: ${getErrorMessage(e)}`,

extensions/ql-vscode/src/databases/local-databases/database-manager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { remove } from "fs-extra";
2929
import { containsPath } from "../../pure/files";
3030
import { DatabaseChangedEvent, DatabaseEventKind } from "./database-events";
3131
import { DatabaseResolver } from "./database-resolver";
32+
import { telemetryListener } from "../../common/vscode/telemetry";
3233

3334
/**
3435
* The name of the key in the workspaceState dictionary in which we
@@ -413,6 +414,7 @@ export class DatabaseManager extends DisposableObject {
413414
// database list had an unexpected type - nothing to be done?
414415
void showAndLogExceptionWithTelemetry(
415416
extLogger,
417+
telemetryListener,
416418
redactableError(
417419
asError(e),
418420
)`Database list loading failed: ${getErrorMessage(e)}`,

extensions/ql-vscode/src/extension.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ import {
9090
import { QLTestAdapterFactory } from "./query-testing/test-adapter";
9191
import { TestUIService } from "./query-testing/test-ui";
9292
import { CompareView } from "./compare/compare-view";
93-
import { initializeTelemetry } from "./common/vscode/telemetry";
93+
import {
94+
initializeTelemetry,
95+
telemetryListener,
96+
} from "./common/vscode/telemetry";
9497
import { ProgressCallback, withProgress } from "./common/vscode/progress";
9598
import { CodeQlStatusBarHandler } from "./status-bar";
9699
import { getPackagingCommands } from "./packaging";
@@ -1134,6 +1137,7 @@ async function showResultsForComparison(
11341137
} catch (e) {
11351138
void showAndLogExceptionWithTelemetry(
11361139
extLogger,
1140+
telemetryListener,
11371141
redactableError(asError(e))`Failed to show results: ${getErrorMessage(
11381142
e,
11391143
)}`,
@@ -1159,16 +1163,16 @@ function addUnhandledRejectionListener() {
11591163
)`Unhandled error: ${getErrorMessage(error)}`;
11601164
// Add a catch so that showAndLogExceptionWithTelemetry fails, we avoid
11611165
// triggering "unhandledRejection" and avoid an infinite loop
1162-
showAndLogExceptionWithTelemetry(extLogger, message).catch(
1163-
(telemetryError: unknown) => {
1164-
void extLogger.log(
1165-
`Failed to send error telemetry: ${getErrorMessage(
1166-
telemetryError,
1167-
)}`,
1168-
);
1169-
void extLogger.log(message.fullMessage);
1170-
},
1171-
);
1166+
showAndLogExceptionWithTelemetry(
1167+
extLogger,
1168+
telemetryListener,
1169+
message,
1170+
).catch((telemetryError: unknown) => {
1171+
void extLogger.log(
1172+
`Failed to send error telemetry: ${getErrorMessage(telemetryError)}`,
1173+
);
1174+
void extLogger.log(message.fullMessage);
1175+
});
11721176
}
11731177
};
11741178

0 commit comments

Comments
 (0)