Skip to content

Commit 160a6cc

Browse files
committed
Use redactable error message for telemetry events
1 parent 4edb831 commit 160a6cc

25 files changed

Lines changed: 220 additions & 195 deletions

extensions/ql-vscode/src/astViewer.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import {
2626
import { commandRunner } from "./commandRunner";
2727
import { DisposableObject } from "./pure/disposable-object";
2828
import { showAndLogExceptionWithTelemetry } from "./helpers";
29-
import { asError } from "./pure/helpers-pure";
29+
import { asError, getErrorMessage } from "./pure/helpers-pure";
30+
import { redactableErrorMessage } from "./pure/errors";
3031

3132
export interface AstItem {
3233
id: BqrsId;
@@ -148,7 +149,12 @@ export class AstViewer extends DisposableObject {
148149
/**/
149150
},
150151
(error: unknown) =>
151-
showAndLogExceptionWithTelemetry(asError(error), "AST_viewer_reveal"),
152+
showAndLogExceptionWithTelemetry(
153+
asError(error),
154+
redactableErrorMessage`Failed to reveal AST: ${getErrorMessage(
155+
error,
156+
)}`,
157+
),
152158
);
153159
}
154160

@@ -209,7 +215,9 @@ export class AstViewer extends DisposableObject {
209215
(error: unknown) =>
210216
showAndLogExceptionWithTelemetry(
211217
asError(error),
212-
"AST_viewer_reveal",
218+
redactableErrorMessage`Failed to reveal AST: ${getErrorMessage(
219+
error,
220+
)}`,
213221
),
214222
);
215223
}

extensions/ql-vscode/src/commandRunner.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { extLogger } from "./common";
1414
import { asError, getErrorMessage, getErrorStack } from "./pure/helpers-pure";
1515
import { telemetryListener } from "./telemetry";
16+
import { redactableErrorMessage } from "./pure/errors";
1617

1718
export class UserCancellationException extends Error {
1819
/**
@@ -128,23 +129,24 @@ export function commandRunner(
128129
try {
129130
return await task(...args);
130131
} catch (e) {
131-
const notificationMessage = `${getErrorMessage(e) || e} (${commandId})`;
132+
const errorMessage = redactableErrorMessage`${
133+
getErrorMessage(e) || e
134+
} (${commandId})`;
132135
error = asError(e);
133136
const errorStack = getErrorStack(e);
134137
if (e instanceof UserCancellationException) {
135138
// User has cancelled this action manually
136139
if (e.silent) {
137-
void extLogger.log(notificationMessage);
140+
void extLogger.log(errorMessage.fullMessage);
138141
} else {
139-
void showAndLogWarningMessage(notificationMessage);
142+
void showAndLogWarningMessage(errorMessage.fullMessage);
140143
}
141144
} else {
142145
// Include the full stack in the error log only.
143146
const fullMessage = errorStack
144-
? `${notificationMessage}\n${errorStack}`
145-
: notificationMessage;
146-
void showAndLogExceptionWithTelemetry(error, "command_failed", {
147-
notificationMessage,
147+
? `${errorMessage.fullMessage}\n${errorStack}`
148+
: errorMessage.fullMessage;
149+
void showAndLogExceptionWithTelemetry(error, errorMessage, {
148150
fullMessage,
149151
extraTelemetryProperties: {
150152
command: commandId,
@@ -185,24 +187,27 @@ export function commandRunnerWithProgress<R>(
185187
try {
186188
return await withProgress(progressOptionsWithDefaults, task, ...args);
187189
} catch (e) {
188-
const notificationMessage = `${getErrorMessage(e) || e} (${commandId})`;
190+
const errorMessage = redactableErrorMessage`${
191+
getErrorMessage(e) || e
192+
} (${commandId})`;
189193
error = asError(e);
190194
const errorStack = getErrorStack(e);
191195
if (e instanceof UserCancellationException) {
192196
// User has cancelled this action manually
193197
if (e.silent) {
194-
void outputLogger.log(notificationMessage);
198+
void outputLogger.log(errorMessage.fullMessage);
195199
} else {
196-
void showAndLogWarningMessage(notificationMessage, { outputLogger });
200+
void showAndLogWarningMessage(errorMessage.fullMessage, {
201+
outputLogger,
202+
});
197203
}
198204
} else {
199205
// Include the full stack in the error log only.
200206
const fullMessage = errorStack
201-
? `${notificationMessage}\n${errorStack}`
202-
: notificationMessage;
203-
void showAndLogExceptionWithTelemetry(error, "command_failed", {
207+
? `${errorMessage.fullMessage}\n${errorStack}`
208+
: errorMessage.fullMessage;
209+
void showAndLogExceptionWithTelemetry(error, errorMessage, {
204210
outputLogger,
205-
notificationMessage,
206211
fullMessage,
207212
extraTelemetryProperties: {
208213
command: commandId,

extensions/ql-vscode/src/contextual/queryResolver.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { createInitialQueryInfo } from "../run-queries-shared";
1818
import { CancellationToken, Uri } from "vscode";
1919
import { ProgressCallback } from "../commandRunner";
2020
import { QueryRunner } from "../queryRunner";
21+
import { redactableErrorMessage } from "../pure/errors";
2122

2223
export async function qlpackOfDatabase(
2324
cli: CodeQLCliServer,
@@ -91,13 +92,13 @@ export async function resolveQueries(
9192
const keyTypeName = nameOfKeyType(keyType);
9293
const keyTypeTag = tagOfKeyType(keyType);
9394
const joinedPacksToSearch = packsToSearch.join(", ");
94-
const errorMessage = `No ${keyTypeName} queries (tagged "${keyTypeTag}") could be found in the \
95+
const errorMessage = redactableErrorMessage`No ${keyTypeName} queries (tagged "${keyTypeTag}") could be found in the \
9596
current library path (tried searching the following packs: ${joinedPacksToSearch}). \
9697
Try upgrading the CodeQL libraries. If that doesn't work, then ${keyTypeName} queries are not yet available \
9798
for this language.`;
9899

99-
const e = new Error(errorMessage);
100-
void showAndLogExceptionWithTelemetry(e, "resolve_queries");
100+
const e = new Error(errorMessage.fullMessage);
101+
void showAndLogExceptionWithTelemetry(e, errorMessage);
101102
throw e;
102103
}
103104

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { QueryRunner } from "./queryRunner";
4242
import { isCanary } from "./config";
4343
import { App } from "./common/app";
4444
import { Credentials } from "./common/authentication";
45+
import { redactableErrorMessage } from "./pure/errors";
4546

4647
enum SortOrder {
4748
NameAsc = "NameAsc",
@@ -347,7 +348,9 @@ export class DatabaseUI extends DisposableObject {
347348
} catch (e) {
348349
void showAndLogExceptionWithTelemetry(
349350
asError(e),
350-
"databases_ui_choose_and_set_database",
351+
redactableErrorMessage`Failed to choose and set database: ${getErrorMessage(
352+
e,
353+
)}`,
351354
);
352355
}
353356
};
@@ -399,7 +402,9 @@ export class DatabaseUI extends DisposableObject {
399402
} catch (e) {
400403
void showAndLogExceptionWithTelemetry(
401404
asError(e),
402-
"databases_ui_remove_orphaned_database",
405+
redactableErrorMessage`Failed to delete orphaned database: ${getErrorMessage(
406+
e,
407+
)}`,
403408
);
404409
failures.push(`${basename(dbDir)}`);
405410
}
@@ -425,7 +430,9 @@ export class DatabaseUI extends DisposableObject {
425430
} catch (e: unknown) {
426431
void showAndLogExceptionWithTelemetry(
427432
asError(e),
428-
"databases_ui_choose_and_set_database",
433+
redactableErrorMessage`Failed to choose and set database: ${getErrorMessage(
434+
e,
435+
)}`,
429436
);
430437
}
431438
};

extensions/ql-vscode/src/databases.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { Logger, extLogger } from "./common";
2222
import { asError, getErrorMessage } from "./pure/helpers-pure";
2323
import { QueryRunner } from "./queryRunner";
2424
import { pathsEqual } from "./pure/files";
25+
import { redactableErrorMessage } from "./pure/errors";
2526

2627
/**
2728
* databases.ts
@@ -796,12 +797,9 @@ export class DatabaseManager extends DisposableObject {
796797
// database list had an unexpected type - nothing to be done?
797798
void showAndLogExceptionWithTelemetry(
798799
asError(e),
799-
"databases_load_persisted_state",
800-
{
801-
notificationMessage: `Database list loading failed: ${getErrorMessage(
802-
e,
803-
)}`,
804-
},
800+
redactableErrorMessage`Database list loading failed: ${getErrorMessage(
801+
e,
802+
)}`,
805803
);
806804
}
807805

extensions/ql-vscode/src/eval-log-viewer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
import { commandRunner } from "./commandRunner";
1212
import { DisposableObject } from "./pure/disposable-object";
1313
import { showAndLogExceptionWithTelemetry } from "./helpers";
14-
import { asError } from "./pure/helpers-pure";
14+
import { asError, getErrorMessage } from "./pure/helpers-pure";
15+
import { redactableErrorMessage } from "./pure/errors";
1516

1617
export interface EvalLogTreeItem {
1718
label?: string;
@@ -108,7 +109,9 @@ export class EvalLogViewer extends DisposableObject {
108109
(err: unknown) =>
109110
showAndLogExceptionWithTelemetry(
110111
asError(err),
111-
"eval_log_viewer_reveal",
112+
redactableErrorMessage`Failed to reveal tree view: ${getErrorMessage(
113+
err,
114+
)}`,
112115
),
113116
);
114117
}

extensions/ql-vscode/src/extension.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ import { VariantAnalysisResultsManager } from "./remote-queries/variant-analysis
138138
import { ExtensionApp } from "./common/vscode/vscode-app";
139139
import { RepositoriesFilterSortStateWithIds } from "./pure/variant-analysis-filter-sort";
140140
import { DbModule } from "./databases/db-module";
141+
import { redactableErrorMessage } from "./pure/errors";
141142

142143
/**
143144
* extension.ts
@@ -717,7 +718,7 @@ async function activateWithInstalledDistribution(
717718
} catch (e) {
718719
void showAndLogExceptionWithTelemetry(
719720
asError(e),
720-
"compare_view_show_results",
721+
redactableErrorMessage`Failed to show results: ${getErrorMessage(e)}`,
721722
);
722723
}
723724
}
@@ -814,16 +815,11 @@ async function activateWithInstalledDistribution(
814815
const errorMessage = getErrorMessage(e).includes(
815816
"Generating qhelp in markdown",
816817
)
817-
? `Could not generate markdown from ${pathToQhelp}: Bad formatting in .qhelp file.`
818-
: `Could not open a preview of the generated file (${absolutePathToMd}).`;
819-
void showAndLogExceptionWithTelemetry(
820-
asError(e),
821-
"preview_query_help",
822-
{
823-
notificationMessage: errorMessage,
824-
fullMessage: `${errorMessage}\n${getErrorMessage(e)}`,
825-
},
826-
);
818+
? redactableErrorMessage`Could not generate markdown from ${pathToQhelp}: Bad formatting in .qhelp file.`
819+
: redactableErrorMessage`Could not open a preview of the generated file (${absolutePathToMd}).`;
820+
void showAndLogExceptionWithTelemetry(asError(e), errorMessage, {
821+
fullMessage: `${errorMessage}\n${getErrorMessage(e)}`,
822+
});
827823
}
828824
}
829825
}

extensions/ql-vscode/src/helpers.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import { CodeQLCliServer, QlpacksInfo } from "./cli";
2121
import { UserCancellationException } from "./commandRunner";
2222
import { extLogger, OutputChannelLogger } from "./common";
2323
import { QueryMetadata } from "./pure/interface-types";
24-
import { ErrorType, telemetryListener } from "./telemetry";
24+
import { telemetryListener } from "./telemetry";
25+
import { RedactableErrorMessage } from "./pure/errors";
2526

2627
// Shared temporary folder for the extension.
2728
export const tmpDir = dirSync({
@@ -47,8 +48,6 @@ export const tmpDirDisposal = {
4748
interface ShowAndLogExceptionOptions extends ShowAndLogOptions {
4849
/** Custom properties to include in the telemetry report. */
4950
extraTelemetryProperties?: { [key: string]: string };
50-
/** An alternate message to use for the notification instead of the message from the `Error`. */
51-
notificationMessage?: string;
5251
}
5352

5453
interface ShowAndLogOptions {
@@ -68,26 +67,23 @@ interface ShowAndLogOptions {
6867
*
6968
* @param error The error message to show, either as a Error or string. Will not be included in the
7069
* telemetry event, and therefore may safely include sensitive information.
71-
* @param telemetryErrorType A safe string that identifies the error, to be included in the
72-
* telemetry event. If not provided, then no telemetry event will be sent.
70+
* @param message A message to show to the user. Will also be included in the telemetry event,
71+
* but only the redacated message will be sent.
7372
* @param options See individual fields on `ShowAndLogExceptionOptions` type.
7473
*
7574
* @return A promise that resolves to the selected item or undefined when being dismissed.
7675
*/
7776
export async function showAndLogExceptionWithTelemetry(
7877
error: Error,
79-
telemetryErrorType: ErrorType,
78+
message: RedactableErrorMessage,
8079
options: ShowAndLogExceptionOptions = {},
8180
): Promise<string | undefined> {
8281
telemetryListener?.sendError(
83-
telemetryErrorType,
82+
message,
8483
error.stack,
8584
options.extraTelemetryProperties,
8685
);
87-
return showAndLogErrorMessage(
88-
options.notificationMessage ?? error.message,
89-
options,
90-
);
86+
return showAndLogErrorMessage(message.fullMessage, options);
9187
}
9288

9389
/**

extensions/ql-vscode/src/interface.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import { AbstractWebview, WebviewPanelConfig } from "./abstract-webview";
6767
import { PAGE_SIZE } from "./config";
6868
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
6969
import { telemetryListener } from "./telemetry";
70+
import { redactableErrorMessage } from "./pure/errors";
7071

7172
/**
7273
* interface.ts
@@ -294,7 +295,9 @@ export class ResultsView extends AbstractWebview<
294295
} catch (e) {
295296
void showAndLogExceptionWithTelemetry(
296297
asError(e),
297-
"results_view_on_message",
298+
redactableErrorMessage`Error handling message from results view: ${getErrorMessage(
299+
e,
300+
)}`,
298301
{
299302
fullMessage: getErrorStack(e),
300303
},
@@ -342,7 +345,7 @@ export class ResultsView extends AbstractWebview<
342345
if (this._displayedQuery === undefined) {
343346
void showAndLogExceptionWithTelemetry(
344347
asError("Failed to sort results since evaluation info was unknown."),
345-
"results_view_displayed_query_undefined",
348+
redactableErrorMessage`Failed to sort results since evaluation info was unknown.`,
346349
);
347350
return;
348351
}
@@ -361,7 +364,7 @@ export class ResultsView extends AbstractWebview<
361364
if (this._displayedQuery === undefined) {
362365
void showAndLogExceptionWithTelemetry(
363366
asError("Failed to sort results since evaluation info was unknown."),
364-
"results_view_displayed_query_undefined",
367+
redactableErrorMessage`Failed to sort results since evaluation info was unknown.`,
365368
);
366369
return;
367370
}
@@ -771,12 +774,9 @@ export class ResultsView extends AbstractWebview<
771774
// trying to render uninterpreted results anyway.
772775
void showAndLogExceptionWithTelemetry(
773776
asError(e),
774-
"results_view_interpret_results_info",
775-
{
776-
notificationMessage: `Showing raw results instead of interpreted ones due to an error. ${getErrorMessage(
777-
e,
778-
)}`,
779-
},
777+
redactableErrorMessage`Showing raw results instead of interpreted ones due to an error. ${getErrorMessage(
778+
e,
779+
)}`,
780780
);
781781
}
782782
}

0 commit comments

Comments
 (0)