Change showAndLog functions to take NotificationLogger

This commit is contained in:
Koen Vlaswinkel
2023-06-12 17:09:25 +02:00
parent d54ee0c0e5
commit 9ff2d568c8
44 changed files with 277 additions and 88 deletions

View File

@@ -160,6 +160,7 @@ export class DistributionManager implements DistributionProvider {
if (this.config.customCodeQlPath) {
if (!(await pathExists(this.config.customCodeQlPath))) {
void showAndLogErrorMessage(
extLogger,
`The CodeQL executable path is specified as "${this.config.customCodeQlPath}" ` +
"by a configuration setting, but a CodeQL executable could not be found at that path. Please check " +
"that a CodeQL executable exists at the specified path or remove the setting.",
@@ -852,6 +853,7 @@ export async function getExecutableFromDirectory(
function warnDeprecatedLauncher() {
void showAndLogWarningMessage(
extLogger,
`The "${deprecatedCodeQlLauncherName()!}" launcher has been deprecated and will be removed in a future version. ` +
`Please use "${codeQlLauncherName()}" instead. It is recommended to update to the latest CodeQL binaries.`,
);

View File

@@ -59,6 +59,7 @@ export async function askForLanguage(
throw new UserCancellationException("Cancelled.");
} else {
void showAndLogErrorMessage(
extLogger,
"Language not found. Language must be specified manually.",
);
}
@@ -67,6 +68,7 @@ export async function askForLanguage(
if (!isQueryLanguage(language)) {
void showAndLogErrorMessage(
extLogger,
`Language '${language}' is not supported. Only languages ${Object.values(
QueryLanguage,
).join(", ")} are supported.`,

View File

@@ -1,4 +1,5 @@
export * from "./logger";
export * from "./notification-logger";
export * from "./tee-logger";
export * from "./vscode/loggers";
export * from "./vscode/output-channel-logger";

View File

@@ -0,0 +1,7 @@
import { Logger } from "./logger";
export interface NotificationLogger extends Logger {
showErrorMessage(message: string): Promise<void>;
showWarningMessage(message: string): Promise<void>;
showInformationMessage(message: string): Promise<void>;
}

View File

@@ -1,11 +1,15 @@
import { window as Window, OutputChannel, Progress } from "vscode";
import { Logger, LogOptions } from "../logger";
import { DisposableObject } from "../../../pure/disposable-object";
import { NotificationLogger } from "../notification-logger";
/**
* A logger that writes messages to an output channel in the VS Code Output tab.
*/
export class OutputChannelLogger extends DisposableObject implements Logger {
export class OutputChannelLogger
extends DisposableObject
implements Logger, NotificationLogger
{
public readonly outputChannel: OutputChannel;
isCustomLogDirectory: boolean;
@@ -42,6 +46,30 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
show(preserveFocus?: boolean): void {
this.outputChannel.show(preserveFocus);
}
async showErrorMessage(message: string): Promise<void> {
await this.showMessage(message, Window.showErrorMessage);
}
async showInformationMessage(message: string): Promise<void> {
await this.showMessage(message, Window.showInformationMessage);
}
async showWarningMessage(message: string): Promise<void> {
await this.showMessage(message, Window.showWarningMessage);
}
private async showMessage(
message: string,
show: (message: string, ...items: string[]) => Thenable<string | undefined>,
): Promise<void> {
const label = "Show Log";
const result = await show(message, label);
if (result === label) {
this.show();
}
}
}
export type ProgressReporter = Progress<{ message: string }>;

View File

@@ -54,9 +54,7 @@ export function registerCommandWithErrorHandling(
if (e.silent) {
void outputLogger.log(errorMessage.fullMessage);
} else {
void showAndLogWarningMessage(errorMessage.fullMessage, {
outputLogger,
});
void showAndLogWarningMessage(outputLogger, errorMessage.fullMessage);
}
} else {
// Include the full stack in the error log only.
@@ -64,8 +62,7 @@ export function registerCommandWithErrorHandling(
const fullMessage = errorStack
? `${errorMessage.fullMessage}\n${errorStack}`
: errorMessage.fullMessage;
void showAndLogExceptionWithTelemetry(errorMessage, {
outputLogger,
void showAndLogExceptionWithTelemetry(outputLogger, errorMessage, {
fullMessage,
extraTelemetryProperties: {
command: commandId,

View File

@@ -8,6 +8,7 @@ import {
getErrorStack,
} from "../../pure/helpers-pure";
import { showAndLogExceptionWithTelemetry } from "./log";
import { extLogger } from "../logging";
export async function tryOpenExternalFile(
commandManager: AppCommandManager,
@@ -34,6 +35,7 @@ the file in the file explorer and dragging it into the workspace.`,
await commandManager.execute("revealFileInOS", uri);
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Failed to reveal file in OS: ${getErrorMessage(e)}`,
@@ -42,6 +44,7 @@ the file in the file explorer and dragging it into the workspace.`,
}
} else {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(asError(e))`Could not open file ${fileLocation}`,
{
fullMessage: `${getErrorMessage(e)}\n${getErrorStack(e)}`,

View File

@@ -1,7 +1,6 @@
import { window } from "vscode";
import { RedactableError } from "../../pure/errors";
import { telemetryListener } from "../../telemetry";
import { extLogger, OutputChannelLogger } from "../logging";
import { NotificationLogger } from "../logging";
interface ShowAndLogExceptionOptions extends ShowAndLogOptions {
/** Custom properties to include in the telemetry report. */
@@ -9,10 +8,6 @@ interface ShowAndLogExceptionOptions extends ShowAndLogOptions {
}
interface ShowAndLogOptions {
/** The output logger that will receive the message. */
outputLogger?: OutputChannelLogger;
/** A set of items that will be rendered as actions in the message. */
items?: string[];
/**
* An alternate message that is added to the log, but not displayed in the popup.
* This is useful for adding extra detail to the logs that would be too noisy for the popup.
@@ -23,34 +18,39 @@ interface ShowAndLogOptions {
/**
* Show an error message, log it to the console, and emit redacted information as telemetry
*
* @param logger The logger that will receive the message.
* @param error The error to show. Only redacted information will be included in the telemetry.
* @param options See individual fields on `ShowAndLogExceptionOptions` type.
*
* @return A promise that resolves to the selected item or undefined when being dismissed.
*/
export async function showAndLogExceptionWithTelemetry(
logger: NotificationLogger,
error: RedactableError,
options: ShowAndLogExceptionOptions = {},
): Promise<string | undefined> {
): Promise<void> {
telemetryListener?.sendError(error, options.extraTelemetryProperties);
return showAndLogErrorMessage(error.fullMessage, options);
return showAndLogErrorMessage(logger, error.fullMessage, options);
}
/**
* Show an error message and log it to the console
*
* @param logger The logger that will receive the message.
* @param message The message to show.
* @param options See individual fields on `ShowAndLogOptions` type.
* @param options? See individual fields on `ShowAndLogOptions` type.
*
* @return A promise that resolves to the selected item or undefined when being dismissed.
*/
export async function showAndLogErrorMessage(
logger: NotificationLogger,
message: string,
options?: ShowAndLogOptions,
): Promise<string | undefined> {
): Promise<void> {
return internalShowAndLog(
logger,
dropLinesExceptInitial(message),
window.showErrorMessage,
logger.showErrorMessage,
{ fullMessage: message, ...options },
);
}
@@ -62,48 +62,53 @@ function dropLinesExceptInitial(message: string, n = 2) {
/**
* Show a warning message and log it to the console
*
* @param logger The logger that will receive the message.
* @param message The message to show.
* @param options See individual fields on `ShowAndLogOptions` type.
* @param options? See individual fields on `ShowAndLogOptions` type.
*
* @return A promise that resolves to the selected item or undefined when being dismissed.
*/
export async function showAndLogWarningMessage(
logger: NotificationLogger,
message: string,
options?: ShowAndLogOptions,
): Promise<string | undefined> {
return internalShowAndLog(message, window.showWarningMessage, options);
): Promise<void> {
return internalShowAndLog(
logger,
message,
logger.showWarningMessage,
options,
);
}
/**
* Show an information message and log it to the console
*
* @param logger The logger that will receive the message.
* @param message The message to show.
* @param options See individual fields on `ShowAndLogOptions` type.
* @param options? See individual fields on `ShowAndLogOptions` type.
*
* @return A promise that resolves to the selected item or undefined when being dismissed.
*/
export async function showAndLogInformationMessage(
logger: NotificationLogger,
message: string,
options?: ShowAndLogOptions,
): Promise<string | undefined> {
return internalShowAndLog(message, window.showInformationMessage, options);
): Promise<void> {
return internalShowAndLog(
logger,
message,
logger.showInformationMessage,
options,
);
}
type ShowMessageFn = (
message: string,
...items: string[]
) => Thenable<string | undefined>;
async function internalShowAndLog(
logger: NotificationLogger,
message: string,
fn: ShowMessageFn,
{ items = [], outputLogger = extLogger, fullMessage }: ShowAndLogOptions = {},
): Promise<string | undefined> {
const label = "Show Log";
void outputLogger.log(fullMessage || message);
const result = await fn(message, label, ...items);
if (result === label) {
outputLogger.show();
}
return result;
fn: (message: string) => Promise<void>,
{ fullMessage }: ShowAndLogOptions = {},
): Promise<void> {
void logger.log(fullMessage || message);
await fn.bind(logger)(message);
}

View File

@@ -4,6 +4,7 @@ import {
TreeViewContextSingleSelectionCommandFunction,
} from "../commands";
import { showAndLogErrorMessage } from "./log";
import { extLogger } from "../logging";
// A hack to match types that are not an array, which is useful to help avoid
// misusing createSingleSelectionCommand, e.g. where T accidentally gets instantiated
@@ -32,7 +33,10 @@ export function createSingleSelectionCommand<T extends NotArray>(
if (multiSelect === undefined || multiSelect.length === 1) {
return f(singleItem);
} else {
void showAndLogErrorMessage(`Please select a single ${itemName}.`);
void showAndLogErrorMessage(
extLogger,
`Please select a single ${itemName}.`,
);
return;
}
};

View File

@@ -5,7 +5,7 @@ import {
ToCompareViewMessage,
QueryCompareResult,
} from "../pure/interface-types";
import { Logger } from "../common";
import { extLogger, Logger } from "../common";
import { CodeQLCliServer } from "../codeql-cli/cli";
import { DatabaseManager } from "../databases/local-databases";
import { jumpToLocation } from "../databases/local-databases/locations";
@@ -152,6 +152,7 @@ export class CompareView extends AbstractWebview<
case "unhandledError":
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
msg.error,
)`Unhandled error in result comparison view: ${msg.error.message}`,

View File

@@ -10,6 +10,7 @@ import { App } from "../common/app";
import { withProgress } from "../common/vscode/progress";
import { pickExtensionPackModelFile } from "./extension-pack-picker";
import { showAndLogErrorMessage } from "../common/vscode/log";
import { extLogger } from "../common";
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
@@ -56,12 +57,13 @@ export class DataExtensionsEditorModule {
"codeQL.openDataExtensionsEditor": async () => {
const db = this.databaseManager.currentDatabaseItem;
if (!db) {
void showAndLogErrorMessage("No database selected");
void showAndLogErrorMessage(extLogger, "No database selected");
return;
}
if (!SUPPORTED_LANGUAGES.includes(db.language)) {
void showAndLogErrorMessage(
extLogger,
`The data extensions editor is not supported for ${db.language} databases.`,
);
return;
@@ -71,6 +73,7 @@ export class DataExtensionsEditorModule {
async (progress, token) => {
if (!(await this.cliServer.cliConstraints.supportsQlpacksKind())) {
void showAndLogErrorMessage(
extLogger,
`This feature requires CodeQL CLI version ${CliVersionConstraint.CLI_VERSION_WITH_QLPACKS_KIND.format()} or later.`,
);
return;

View File

@@ -208,6 +208,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
if (!existingModeledMethods) {
void showAndLogErrorMessage(
extLogger,
`Failed to parse data extension YAML ${this.modelFile.filename}.`,
);
return;
@@ -219,6 +220,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
});
} catch (e: unknown) {
void showAndLogErrorMessage(
extLogger,
`Unable to read data extension YAML ${
this.modelFile.filename
}: ${getErrorMessage(e)}`,
@@ -276,6 +278,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
await this.clearProgress();
} catch (err) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(err),
)`Failed to load external API usages: ${getErrorMessage(err)}`,
@@ -341,6 +344,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
});
} catch (e: unknown) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Failed to generate flow model: ${getErrorMessage(e)}`,
@@ -474,6 +478,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
if (e instanceof RequestError && e.status === 429) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(e)`Rate limit hit, please try again soon.`,
);
return null;

View File

@@ -15,6 +15,7 @@ import { getErrorMessage } from "../pure/helpers-pure";
import { ExtensionPack, ExtensionPackModelFile } from "./shared/extension-pack";
import { showAndLogErrorMessage } from "../common/vscode/log";
import { containsPath } from "../pure/files";
import { extLogger } from "../common";
const maxStep = 3;
@@ -85,6 +86,7 @@ async function pickExtensionPack(
Object.entries(extensionPacksInfo).map(async ([name, paths]) => {
if (paths.length !== 1) {
void showAndLogErrorMessage(
extLogger,
`Extension pack ${name} resolves to multiple paths`,
{
fullMessage: `Extension pack ${name} resolves to multiple paths: ${paths.join(
@@ -102,11 +104,15 @@ async function pickExtensionPack(
try {
extensionPack = await readExtensionPack(path);
} catch (e: unknown) {
void showAndLogErrorMessage(`Could not read extension pack ${name}`, {
fullMessage: `Could not read extension pack ${name} at ${path}: ${getErrorMessage(
e,
)}`,
});
void showAndLogErrorMessage(
extLogger,
`Could not read extension pack ${name}`,
{
fullMessage: `Could not read extension pack ${name} at ${path}: ${getErrorMessage(
e,
)}`,
},
);
return undefined;
}

View File

@@ -3,7 +3,7 @@ import { dir } from "tmp-promise";
import { writeFile } from "fs-extra";
import { dump as dumpYaml } from "js-yaml";
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
import { TeeLogger } from "../common";
import { extLogger, TeeLogger } from "../common";
import { isQueryLanguage } from "../common/query-language";
import { CancellationToken } from "vscode";
import { CodeQLCliServer } from "../codeql-cli/cli";
@@ -41,6 +41,7 @@ export async function runQuery({
if (!isQueryLanguage(databaseItem.language)) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Unsupported database language ${databaseItem.language}`,
);
return;
@@ -49,6 +50,7 @@ export async function runQuery({
const query = fetchExternalApiQueries[databaseItem.language];
if (!query) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`No external API usage query found for language ${databaseItem.language}`,
);
return;
@@ -104,6 +106,7 @@ export async function runQuery({
if (completedQuery.resultType !== QueryResultType.SUCCESS) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`External API usage query failed: ${
completedQuery.message ?? "No message"
}`,
@@ -126,6 +129,7 @@ export async function readQueryResults({
const bqrsInfo = await cliServer.bqrsInfo(bqrsPath);
if (bqrsInfo["result-sets"].length !== 1) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Expected exactly one result set, got ${bqrsInfo["result-sets"].length}`,
);
return undefined;

View File

@@ -3,7 +3,7 @@ import { DatabaseItem } from "../databases/local-databases";
import { basename } from "path";
import { QueryRunner } from "../query-server";
import { CodeQLCliServer } from "../codeql-cli/cli";
import { TeeLogger } from "../common";
import { extLogger, TeeLogger } from "../common";
import { extensiblePredicateDefinitions } from "./predicates";
import { ProgressCallback } from "../common/vscode/progress";
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
@@ -81,6 +81,7 @@ async function getModeledMethodsFromFlow(
): Promise<ModeledMethodWithSignature[]> {
if (queryPath === undefined) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Failed to find ${type} query`,
);
return [];
@@ -115,6 +116,7 @@ async function getModeledMethodsFromFlow(
);
if (queryResult.resultType !== QueryResultType.SUCCESS) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Failed to run ${basename(queryPath)} query: ${
queryResult.message ?? "No message"
}`,
@@ -127,6 +129,7 @@ async function getModeledMethodsFromFlow(
const bqrsInfo = await cliServer.bqrsInfo(bqrsPath);
if (bqrsInfo["result-sets"].length !== 1) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Expected exactly one result set, got ${
bqrsInfo["result-sets"].length
} for ${basename(queryPath)}`,

View File

@@ -4,6 +4,7 @@ import { Octokit } from "@octokit/rest";
import { Progress, CancellationToken } from "vscode";
import { Credentials } from "../common/authentication";
import { showAndLogWarningMessage } from "../common/vscode/log";
import { extLogger } from "../common";
export async function getCodeSearchRepositories(
query: string,
@@ -53,6 +54,7 @@ async function provideOctokitWithThrottling(
throttle: {
onRateLimit: (retryAfter: number, options: any): boolean => {
void showAndLogWarningMessage(
extLogger,
`Rate Limit detected for request ${options.method} ${options.url}. Retrying after ${retryAfter} seconds!`,
);
@@ -60,6 +62,7 @@ async function provideOctokitWithThrottling(
},
onSecondaryRateLimit: (_retryAfter: number, options: any): void => {
void showAndLogWarningMessage(
extLogger,
`Secondary Rate Limit detected for request ${options.method} ${options.url}`,
);
},

View File

@@ -70,6 +70,7 @@ export async function promptImportInternetDatabase(
if (item) {
await commandManager.execute("codeQLDatabases.focus");
void showAndLogInformationMessage(
extLogger,
"Database downloaded and imported successfully.",
);
}
@@ -115,6 +116,7 @@ export async function promptImportGithubDatabase(
if (databaseItem) {
await commandManager.execute("codeQLDatabases.focus");
void showAndLogInformationMessage(
extLogger,
"Database downloaded and imported successfully.",
);
return databaseItem;
@@ -246,6 +248,7 @@ export async function importArchiveDatabase(
if (item) {
await commandManager.execute("codeQLDatabases.focus");
void showAndLogInformationMessage(
extLogger,
"Database unzipped and imported successfully.",
);
}

View File

@@ -281,6 +281,7 @@ export class DatabaseUI extends DisposableObject {
await this.chooseAndSetDatabase(true, { progress, token });
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Failed to choose and set database: ${getErrorMessage(e)}`,
@@ -418,6 +419,7 @@ export class DatabaseUI extends DisposableObject {
await remove(dbDir);
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Failed to delete orphaned database: ${getErrorMessage(e)}`,
@@ -430,6 +432,7 @@ export class DatabaseUI extends DisposableObject {
if (failures.length) {
const dirname = path_dirname(failures[0]);
void showAndLogErrorMessage(
extLogger,
`Failed to delete unused databases (${failures.join(
", ",
)}).\nTo delete unused databases, please remove them manually from the storage folder ${dirname}.`,
@@ -445,6 +448,7 @@ export class DatabaseUI extends DisposableObject {
await this.chooseAndSetDatabase(false, { progress, token });
} catch (e: unknown) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Failed to choose and set database: ${getErrorMessage(e)}`,

View File

@@ -412,6 +412,7 @@ export class DatabaseManager extends DisposableObject {
} catch (e) {
// database list had an unexpected type - nothing to be done?
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Database list loading failed: ${getErrorMessage(e)}`,

View File

@@ -12,6 +12,7 @@ import {
showAndLogInformationMessage,
showAndLogWarningMessage,
} from "../../common/vscode/log";
import { extLogger } from "../../common";
export class DatabaseResolver {
public static async resolveDatabaseContents(
@@ -107,6 +108,7 @@ async function findDataset(parentDirectory: string): Promise<vscode.Uri> {
const dbAbsolutePath = join(parentDirectory, dbRelativePaths[0]);
if (dbRelativePaths.length > 1) {
void showAndLogWarningMessage(
extLogger,
`Found multiple dataset directories in database, using '${dbAbsolutePath}'.`,
);
}
@@ -138,6 +140,7 @@ export async function findSourceArchive(
}
void showAndLogInformationMessage(
extLogger,
`Could not find source archive for database '${databasePath}'. Assuming paths are absolute.`,
);
return undefined;

View File

@@ -38,6 +38,7 @@ import {
showAndLogErrorMessage,
showAndLogInformationMessage,
} from "../../common/vscode/log";
import { extLogger } from "../../common";
export interface RemoteDatabaseQuickPickItem extends QuickPickItem {
remoteDatabaseKind: string;
@@ -174,12 +175,18 @@ export class DbPanel extends DisposableObject {
const nwo = getNwoFromGitHubUrl(repoName) || repoName;
if (!isValidGitHubNwo(nwo)) {
void showAndLogErrorMessage(`Invalid GitHub repository: ${repoName}`);
void showAndLogErrorMessage(
extLogger,
`Invalid GitHub repository: ${repoName}`,
);
return;
}
if (this.dbManager.doesRemoteRepoExist(nwo, parentList)) {
void showAndLogErrorMessage(`The repository '${nwo}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The repository '${nwo}' already exists`,
);
return;
}
@@ -199,12 +206,18 @@ export class DbPanel extends DisposableObject {
const owner = getOwnerFromGitHubUrl(ownerName) || ownerName;
if (!isValidGitHubOwner(owner)) {
void showAndLogErrorMessage(`Invalid user or organization: ${owner}`);
void showAndLogErrorMessage(
extLogger,
`Invalid user or organization: ${owner}`,
);
return;
}
if (this.dbManager.doesRemoteOwnerExist(owner)) {
void showAndLogErrorMessage(`The owner '${owner}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The owner '${owner}' already exists`,
);
return;
}
@@ -223,7 +236,10 @@ export class DbPanel extends DisposableObject {
}
if (this.dbManager.doesListExist(listKind, listName)) {
void showAndLogErrorMessage(`The list '${listName}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The list '${listName}' already exists`,
);
return;
}
@@ -287,7 +303,10 @@ export class DbPanel extends DisposableObject {
}
if (this.dbManager.doesListExist(DbListKind.Local, newName)) {
void showAndLogErrorMessage(`The list '${newName}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The list '${newName}' already exists`,
);
return;
}
@@ -303,7 +322,10 @@ export class DbPanel extends DisposableObject {
}
if (this.dbManager.doesLocalDbExist(newName, dbItem.parentListName)) {
void showAndLogErrorMessage(`The database '${newName}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The database '${newName}' already exists`,
);
return;
}
@@ -319,7 +341,10 @@ export class DbPanel extends DisposableObject {
}
if (this.dbManager.doesListExist(DbListKind.Remote, newName)) {
void showAndLogErrorMessage(`The list '${newName}' already exists`);
void showAndLogErrorMessage(
extLogger,
`The list '${newName}' already exists`,
);
return;
}
@@ -402,7 +427,7 @@ export class DbPanel extends DisposableObject {
);
token.onCancellationRequested(() => {
void showAndLogInformationMessage("Code search cancelled");
void showAndLogInformationMessage(extLogger, "Code search cancelled");
return;
});
@@ -471,6 +496,7 @@ export class DbPanel extends DisposableObject {
}
void showAndLogErrorMessage(
extLogger,
`An error occurred while setting up the controller repository: ${getErrorMessage(
e,
)}`,

View File

@@ -10,6 +10,7 @@ import { getQuickEvalContext, validateQueryPath } from "../run-queries-shared";
import * as CodeQLProtocol from "./debug-protocol";
import { getErrorMessage } from "../pure/helpers-pure";
import { showAndLogErrorMessage } from "../common/vscode/log";
import { extLogger } from "../common";
/**
* The CodeQL launch arguments, as specified in "launch.json".
@@ -126,7 +127,7 @@ export class QLDebugConfigurationProvider
// Any unhandled exception will result in an OS-native error message box, which seems ugly.
// We'll just show a real VS Code error message, then return null to prevent the debug session
// from starting.
void showAndLogErrorMessage(getErrorMessage(e));
void showAndLogErrorMessage(extLogger, getErrorMessage(e));
return null;
}
}

View File

@@ -74,6 +74,7 @@ import {
QuickEvalCodeLensProvider,
} from "./local-queries";
import {
BaseLogger,
extLogger,
ideServerLogger,
ProgressReporter,
@@ -193,9 +194,10 @@ function getCommands(
}
},
]);
void showAndLogInformationMessage("CodeQL Query Server restarted.", {
outputLogger: queryServerLogger,
});
void showAndLogInformationMessage(
queryServerLogger,
"CodeQL Query Server restarted.",
);
},
{
title: "Restarting Query Server",
@@ -215,7 +217,7 @@ function getCommands(
extension?.packageJSON.version
} \nCodeQL CLI version: ${await getCliVersion()} \nPlatform: ${platform()} ${arch()}`;
await env.clipboard.writeText(text);
void showAndLogInformationMessage(text);
void showAndLogInformationMessage(extLogger, text);
},
"codeQL.authenticateToGitHub": async () => {
/**
@@ -225,6 +227,7 @@ function getCommands(
const octokit = await app.credentials.getOctokit();
const userInfo = await octokit.users.getAuthenticated();
void showAndLogInformationMessage(
extLogger,
`Authenticated to GitHub as user: ${userInfo.data.login}`,
);
},
@@ -341,6 +344,7 @@ export async function activate(
registerErrorStubs([checkForUpdatesCommand], (command) => async () => {
void showAndLogErrorMessage(
extLogger,
`Can't execute ${command}: waiting to finish loading CodeQL CLI.`,
);
});
@@ -428,6 +432,7 @@ export async function activate(
}
void showAndLogWarningMessage(
extLogger,
`You are using an unsupported version of the CodeQL CLI (${ver}). ` +
`The minimum supported version is ${CliVersionConstraint.OLDEST_SUPPORTED_CLI_VERSION}. ` +
`Please upgrade to a newer version of the CodeQL CLI.`,
@@ -449,7 +454,7 @@ async function installOrUpdateDistributionWithProgressTitle(
const minSecondsSinceLastUpdateCheck = config.isUserInitiated ? 0 : 86400;
const noUpdatesLoggingFunc = config.shouldDisplayMessageWhenNoUpdates
? showAndLogInformationMessage
: async (message: string) => void extLogger.log(message);
: async (logger: BaseLogger, message: string) => void logger.log(message);
const result =
await distributionManager.checkForUpdatesToExtensionManagedDistribution(
minSecondsSinceLastUpdateCheck,
@@ -467,10 +472,11 @@ async function installOrUpdateDistributionWithProgressTitle(
);
break;
case DistributionUpdateCheckResultKind.AlreadyUpToDate:
await noUpdatesLoggingFunc("CodeQL CLI already up to date.");
await noUpdatesLoggingFunc(extLogger, "CodeQL CLI already up to date.");
break;
case DistributionUpdateCheckResultKind.InvalidLocation:
await noUpdatesLoggingFunc(
extLogger,
"CodeQL CLI is installed externally so could not be updated.",
);
break;
@@ -502,6 +508,7 @@ async function installOrUpdateDistributionWithProgressTitle(
await ctx.globalState.update(shouldUpdateOnNextActivationKey, false);
void showAndLogInformationMessage(
extLogger,
`CodeQL CLI updated to version "${result.updatedRelease.name}".`,
);
}
@@ -556,6 +563,7 @@ async function installOrUpdateDistribution(
if (e instanceof GithubRateLimitedError) {
void alertFunction(
extLogger,
`Rate limited while trying to ${taskDescription}. Please try again after ` +
`your rate limit window resets at ${e.rateLimitResetDate.toLocaleString(
env.language,
@@ -563,10 +571,11 @@ async function installOrUpdateDistribution(
);
} else if (e instanceof GithubApiError) {
void alertFunction(
extLogger,
`Encountered GitHub API error while trying to ${taskDescription}. ${e}`,
);
}
void alertFunction(`Unable to ${taskDescription}. ${e}`);
void alertFunction(extLogger, `Unable to ${taskDescription}. ${e}`);
} finally {
isInstallingOrUpdatingDistribution = false;
}
@@ -598,6 +607,7 @@ async function getDistributionDisplayingDistributionWarnings(
})();
void showAndLogWarningMessage(
extLogger,
`The current version of the CodeQL CLI (${result.version.raw}) ` +
`is incompatible with this extension. ${fixGuidanceMessage}`,
);
@@ -605,12 +615,16 @@ async function getDistributionDisplayingDistributionWarnings(
}
case FindDistributionResultKind.UnknownCompatibilityDistribution:
void showAndLogWarningMessage(
extLogger,
"Compatibility with the configured CodeQL CLI could not be determined. " +
"You may experience problems using the extension.",
);
break;
case FindDistributionResultKind.NoDistribution:
void showAndLogErrorMessage("The CodeQL CLI could not be found.");
void showAndLogErrorMessage(
extLogger,
"The CodeQL CLI could not be found.",
);
break;
default:
assertNever(result);
@@ -652,14 +666,17 @@ async function installOrUpdateThenTryActivate(
if (distributionResult.kind === FindDistributionResultKind.NoDistribution) {
registerErrorStubs([checkForUpdatesCommand], (command) => async () => {
void extLogger.log(`Can't execute ${command}: missing CodeQL CLI.`);
const showLogName = "Show Log";
const installActionName = "Install CodeQL CLI";
const chosenAction = await showAndLogErrorMessage(
const chosenAction = await Window.showErrorMessage(
`Can't execute ${command}: missing CodeQL CLI.`,
{
items: [installActionName],
},
showLogName,
installActionName,
);
if (chosenAction === installActionName) {
if (chosenAction === showLogName) {
extLogger.show();
} else if (chosenAction === installActionName) {
await installOrUpdateThenTryActivate(
ctx,
app,
@@ -1116,6 +1133,7 @@ async function showResultsForComparison(
await compareView.showResults(from, to);
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(asError(e))`Failed to show results: ${getErrorMessage(
e,
)}`,
@@ -1141,7 +1159,7 @@ function addUnhandledRejectionListener() {
)`Unhandled error: ${getErrorMessage(error)}`;
// Add a catch so that showAndLogExceptionWithTelemetry fails, we avoid
// triggering "unhandledRejection" and avoid an infinite loop
showAndLogExceptionWithTelemetry(message).catch(
showAndLogExceptionWithTelemetry(extLogger, message).catch(
(telemetryError: unknown) => {
void extLogger.log(
`Failed to send error telemetry: ${getErrorMessage(
@@ -1250,6 +1268,7 @@ async function assertVSCodeVersionGreaterThan(
const parsedMinVersion = parse(minVersion);
if (!parsedVersion || !parsedMinVersion) {
void showAndLogWarningMessage(
extLogger,
`Could not do a version check of vscode because could not parse version number: actual vscode version ${vscodeVersion} or minimum supported vscode version ${minVersion}.`,
);
return;
@@ -1269,6 +1288,7 @@ async function assertVSCodeVersionGreaterThan(
}
} catch (e) {
void showAndLogWarningMessage(
extLogger,
`Could not do a version check because of an error: ${getErrorMessage(e)}`,
);
}

View File

@@ -28,6 +28,7 @@ import { asError, getErrorMessage } from "../../pure/helpers-pure";
import { redactableError } from "../../pure/errors";
import { AstViewerCommands } from "../../common/commands";
import { showAndLogExceptionWithTelemetry } from "../../common/vscode/log";
import { extLogger } from "../../common";
export interface AstItem {
id: BqrsId;
@@ -145,6 +146,7 @@ export class AstViewer extends DisposableObject {
},
(error: unknown) =>
showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(error),
)`Failed to reveal AST: ${getErrorMessage(error)}`,
@@ -208,6 +210,7 @@ export class AstViewer extends DisposableObject {
},
(error: unknown) =>
showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(error),
)`Failed to reveal AST: ${getErrorMessage(error)}`,

View File

@@ -102,7 +102,7 @@ current library path (tried searching the following packs: ${joinedPacksToSearch
Try upgrading the CodeQL libraries. If that doesn't work, then ${keyTypeName} queries are not yet available \
for this language.`;
void showAndLogExceptionWithTelemetry(error);
void showAndLogExceptionWithTelemetry(extLogger, error);
throw error;
}

View File

@@ -6,6 +6,7 @@ import { getErrorMessage } from "../pure/helpers-pure";
import { redactableError } from "../pure/errors";
import { AppCommandManager, QueryEditorCommands } from "../common/commands";
import { showAndLogExceptionWithTelemetry } from "../common/vscode/log";
import { extLogger } from "../common";
type QueryEditorOptions = {
commandManager: AppCommandManager;
@@ -79,7 +80,7 @@ async function previewQueryHelp(
)
? redactableError`Could not generate markdown from ${pathToQhelp}: Bad formatting in .qhelp file.`
: redactableError`Could not open a preview of the generated file (${absolutePathToMd}).`;
void showAndLogExceptionWithTelemetry(errorMessage, {
void showAndLogExceptionWithTelemetry(extLogger, errorMessage, {
fullMessage: `${errorMessage}\n${getErrorMessage(e)}`,
});
}

View File

@@ -323,6 +323,7 @@ export class LocalQueries extends DisposableObject {
if (this.queryRunner.customLogDirectory) {
void showAndLogWarningMessage(
extLogger,
`Custom log directories are no longer supported. The "codeQL.runningQueries.customLogDirectory" setting is deprecated. Unset the setting to stop seeing this message. Query logs saved to ${outputDir.logPath}`,
);
}
@@ -469,6 +470,7 @@ export class LocalQueries extends DisposableObject {
let filteredDBs = this.databaseManager.databaseItems;
if (filteredDBs.length === 0) {
void showAndLogErrorMessage(
extLogger,
"No databases found. Please add a suitable database to your workspace.",
);
return;
@@ -481,6 +483,7 @@ export class LocalQueries extends DisposableObject {
);
if (filteredDBs.length === 0) {
void showAndLogErrorMessage(
extLogger,
`No databases found for language ${queryLanguage}. Please add a suitable database to your workspace.`,
);
return;
@@ -519,13 +522,14 @@ export class LocalQueries extends DisposableObject {
if (skippedDatabases.length > 0) {
void extLogger.log(`Errors:\n${errors.join("\n")}`);
void showAndLogWarningMessage(
extLogger,
`The following databases were skipped:\n${skippedDatabases.join(
"\n",
)}.\nFor details about the errors, see the logs.`,
);
}
} else {
void showAndLogErrorMessage("No databases selected.");
void showAndLogErrorMessage(extLogger, "No databases selected.");
}
}

View File

@@ -1,4 +1,4 @@
import { BaseLogger, Logger } from "../common";
import { BaseLogger, extLogger, Logger } from "../common";
import { CoreQueryResults } from "../query-server";
import { QueryHistoryManager } from "../query-history/query-history-manager";
import { DatabaseItem } from "../databases/local-databases";
@@ -119,6 +119,7 @@ export class LocalQueryRun {
// Raw evaluator log was not found. Notify the user, unless we know why it wasn't found.
if (resultType === QueryResultType.SUCCESS) {
void showAndLogWarningMessage(
extLogger,
`Failed to write structured evaluator log to ${outputDir.evalLogPath}.`,
);
} else {
@@ -155,7 +156,7 @@ export class LocalQueryRun {
const message = results.message
? redactableError`Failed to run query: ${results.message}`
: redactableError`Failed to run query`;
void showAndLogExceptionWithTelemetry(message);
void showAndLogExceptionWithTelemetry(extLogger, message);
}
const message = formatResultMessage(results);
const successful = results.resultType === QueryResultType.SUCCESS;

View File

@@ -40,7 +40,7 @@ import {
getDefaultResultSetName,
ParsedResultSets,
} from "../pure/interface-types";
import { Logger } from "../common";
import { extLogger, Logger } from "../common";
import {
CompletedQueryInfo,
interpretResultsSarif,
@@ -319,6 +319,7 @@ export class ResultsView extends AbstractWebview<
break;
case "unhandledError":
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
msg.error,
)`Unhandled error in results view: ${msg.error.message}`,
@@ -329,6 +330,7 @@ export class ResultsView extends AbstractWebview<
}
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Error handling message from results view: ${getErrorMessage(e)}`,
@@ -378,6 +380,7 @@ export class ResultsView extends AbstractWebview<
): Promise<void> {
if (this._displayedQuery === undefined) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Failed to sort results since evaluation info was unknown.`,
);
return;
@@ -396,6 +399,7 @@ export class ResultsView extends AbstractWebview<
): Promise<void> {
if (this._displayedQuery === undefined) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Failed to sort results since evaluation info was unknown.`,
);
return;
@@ -806,6 +810,7 @@ export class ResultsView extends AbstractWebview<
// If interpretation fails, accept the error and continue
// trying to render uninterpreted results anyway.
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Showing raw results instead of interpreted ones due to an error. ${getErrorMessage(

View File

@@ -87,9 +87,13 @@ export async function handleDownloadPacks(
});
try {
await cliServer.packDownload(packsToDownload);
void showAndLogInformationMessage("Finished downloading packs.");
void showAndLogInformationMessage(
extLogger,
"Finished downloading packs.",
);
} catch (error) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(error),
)`Unable to download all packs. See log for more details.`,
@@ -165,6 +169,7 @@ export async function handleInstallPackDependencies(
);
} else {
void showAndLogInformationMessage(
extLogger,
"Finished installing pack dependencies.",
);
}

View File

@@ -13,6 +13,7 @@ import { asError, getErrorMessage } from "../pure/helpers-pure";
import { redactableError } from "../pure/errors";
import { EvalLogViewerCommands } from "../common/commands";
import { showAndLogExceptionWithTelemetry } from "../common/vscode/log";
import { extLogger } from "../common";
export interface EvalLogTreeItem {
label?: string;
@@ -109,6 +110,7 @@ export class EvalLogViewer extends DisposableObject {
},
(err: unknown) =>
showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(err),
)`Failed to reveal tree view: ${getErrorMessage(err)}`,

View File

@@ -628,6 +628,7 @@ export class QueryHistoryManager extends DisposableObject {
toItem = await this.findOtherQueryToCompare(fromItem, multiSelect);
} catch (e) {
void showAndLogErrorMessage(
extLogger,
`Failed to compare queries: ${getErrorMessage(e)}`,
);
}
@@ -672,7 +673,7 @@ export class QueryHistoryManager extends DisposableObject {
item.completedQuery.logFileLocation,
);
} else {
void showAndLogWarningMessage("No log file available");
void showAndLogWarningMessage(extLogger, "No log file available");
}
}
@@ -740,18 +741,21 @@ export class QueryHistoryManager extends DisposableObject {
private warnNoEvalLogs() {
void showAndLogWarningMessage(
extLogger,
`Evaluator log, summary, and viewer are not available for this run. Perhaps it failed before evaluation, or you are running with a version of CodeQL before ' + ${CliVersionConstraint.CLI_VERSION_WITH_PER_QUERY_EVAL_LOG}?`,
);
}
private warnInProgressEvalLogSummary() {
void showAndLogWarningMessage(
extLogger,
'The evaluator log summary is still being generated for this run. Please try again later. The summary generation process is tracked in the "CodeQL Extension Log" view.',
);
}
private warnInProgressEvalLogViewer() {
void showAndLogWarningMessage(
extLogger,
"The viewer's data is still being generated for this run. Please try again or re-run the query.",
);
}
@@ -868,6 +872,7 @@ export class QueryHistoryManager extends DisposableObject {
} else {
const label = this.labelProvider.getLabel(item);
void showAndLogInformationMessage(
extLogger,
`Query ${label} has no interpreted results.`,
);
}

View File

@@ -13,6 +13,7 @@ import { QueryHistoryDto, QueryHistoryItemDto } from "./query-history-dto";
import { mapQueryHistoryToDomainModel } from "./query-history-dto-mapper";
import { mapQueryHistoryToDto } from "./query-history-domain-mapper";
import { showAndLogExceptionWithTelemetry } from "../../common/vscode/log";
import { extLogger } from "../../common";
const ALLOWED_QUERY_HISTORY_VERSIONS = [1, 2];
@@ -30,6 +31,7 @@ export async function readQueryHistoryFromFile(
if (!ALLOWED_QUERY_HISTORY_VERSIONS.includes(obj.version)) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Can't parse query history. Unsupported query history format: v${obj.version}.`,
);
return [];
@@ -65,6 +67,7 @@ export async function readQueryHistoryFromFile(
return filteredDomainModels;
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(asError(e))`Error loading query history.`,
{
fullMessage: `Error loading query history.\n${getErrorStack(e)}`,

View File

@@ -321,6 +321,7 @@ export async function compileAndRunQueryAgainstDatabaseCore(
): Promise<CoreQueryResults> {
if (extensionPacks !== undefined && extensionPacks.length > 0) {
void showAndLogWarningMessage(
extLogger,
"Legacy query server does not support extension packs.",
);
}
@@ -386,6 +387,7 @@ export async function compileAndRunQueryAgainstDatabaseCore(
}
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Couldn't resolve available ML models for ${qlProgram.queryPath}. Running the query without any ML models: ${e}.`,
@@ -444,7 +446,7 @@ export async function compileAndRunQueryAgainstDatabaseCore(
? redactableError`${result.message}`
: redactableError`Failed to run query`;
void extLogger.log(error.fullMessage);
void showAndLogExceptionWithTelemetry(error);
void showAndLogExceptionWithTelemetry(extLogger, error);
}
return translateLegacyResult(result);

View File

@@ -206,6 +206,7 @@ export async function upgradeDatabaseExplicit(
);
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
asError(e),
)`Compilation of database upgrades failed: ${getErrorMessage(e)}`,
@@ -220,6 +221,7 @@ export async function upgradeDatabaseExplicit(
? redactableError`${compileUpgradeResult.error}`
: redactableError`[no error message available]`;
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`Compilation of database upgrades failed: ${error}`,
);
return;
@@ -253,6 +255,7 @@ export async function upgradeDatabaseExplicit(
return result;
} catch (e) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(asError(e))`Database upgrade failed: ${getErrorMessage(
e,
)}`,

View File

@@ -5,7 +5,7 @@ import { CancellationToken } from "vscode";
import { createMessageConnection, RequestType } from "vscode-jsonrpc/node";
import * as cli from "../codeql-cli/cli";
import { QueryServerConfig } from "../config";
import { Logger, ProgressReporter } from "../common";
import { extLogger, Logger, ProgressReporter } from "../common";
import {
progress,
ProgressMessage,
@@ -131,6 +131,7 @@ export class QueryServerClient extends DisposableObject {
);
} else {
void showAndLogErrorMessage(
extLogger,
"The CodeQL query server has unexpectedly terminated too many times. Please check the logs for errors. You can manually restart the query server using the command 'CodeQL: Restart query server'.",
);
// Make sure we dispose anyway to reject all pending requests.

View File

@@ -5,7 +5,7 @@ import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
import { asError, getErrorMessage } from "../pure/helpers-pure";
import { redactableError } from "../pure/errors";
import { access } from "fs-extra";
import { BaseLogger } from "../common";
import { BaseLogger, extLogger } from "../common";
import { DisposableObject } from "../pure/disposable-object";
import {
showAndLogExceptionWithTelemetry,
@@ -88,6 +88,7 @@ export class TestRunner extends DisposableObject {
// Explorer UI swallows any thrown exception without reporting it to the user.
// So we need to display the error message ourselves and then rethrow.
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(asError(e))`Cannot remove database ${
database.name
}: ${getErrorMessage(e)}`,
@@ -128,7 +129,10 @@ export class TestRunner extends DisposableObject {
// This method is invoked from Test Explorer UI, and testing indicates that Test
// Explorer UI swallows any thrown exception without reporting it to the user.
// So we need to display the error message ourselves and then rethrow.
void showAndLogWarningMessage(`Cannot reopen database ${uri}: ${e}`);
void showAndLogWarningMessage(
extLogger,
`Cannot reopen database ${uri}: ${e}`,
);
throw e;
}
}

View File

@@ -261,7 +261,7 @@ export class QueryEvaluationInfo extends QueryOutputDir {
): Promise<boolean> {
const resultSet = await this.chooseResultSet(cliServer);
if (!resultSet) {
void showAndLogWarningMessage("Query has no result set.");
void showAndLogWarningMessage(extLogger, "Query has no result set.");
return false;
}
let stopDecoding = false;
@@ -659,6 +659,7 @@ async function generateHumanReadableLogSummary(
return true;
} catch (e) {
void showAndLogWarningMessage(
extLogger,
`Failed to generate human-readable structured evaluator log summary. Reason: ${getErrorMessage(
e,
)}`,
@@ -682,6 +683,7 @@ export async function logEndSummary(
void logger.log(endSummaryContent);
} catch (e) {
void showAndLogWarningMessage(
extLogger,
`Could not read structured evaluator log end of summary file at ${endSummary}.`,
);
}

View File

@@ -12,6 +12,7 @@ import {
import { DataFlowPaths } from "./shared/data-flow-paths";
import { redactableError } from "../pure/errors";
import { showAndLogExceptionWithTelemetry } from "../common/vscode/log";
import { extLogger } from "../common";
export class DataFlowPathsView extends AbstractWebview<
ToDataFlowPathsMessage,
@@ -59,6 +60,7 @@ export class DataFlowPathsView extends AbstractWebview<
break;
case "unhandledError":
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
msg.error,
)`Unhandled error in data flow paths view: ${msg.error.message}`,

View File

@@ -3,6 +3,7 @@ import { URLSearchParams } from "url";
import { SHOW_QUERY_TEXT_MSG } from "../query-history/query-history-manager";
import { VariantAnalysisManager } from "./variant-analysis-manager";
import { showAndLogWarningMessage } from "../common/vscode/log";
import { extLogger } from "../common";
export const createVariantAnalysisContentProvider = (
variantAnalysisManager: VariantAnalysisManager,
@@ -13,6 +14,7 @@ export const createVariantAnalysisContentProvider = (
const variantAnalysisIdString = params.get("variantAnalysisId");
if (!variantAnalysisIdString) {
void showAndLogWarningMessage(
extLogger,
"Unable to show query text. No variant analysis ID provided.",
);
return undefined;
@@ -24,6 +26,7 @@ export const createVariantAnalysisContentProvider = (
);
if (!variantAnalysis) {
void showAndLogWarningMessage(
extLogger,
"Unable to show query text. No variant analysis found.",
);
return undefined;

View File

@@ -256,6 +256,7 @@ export class VariantAnalysisManager
await this.onVariantAnalysisSubmitted(processedVariantAnalysis);
void showAndLogInformationMessage(
extLogger,
`Variant analysis ${processedVariantAnalysis.query.name} submitted for processing`,
);
@@ -328,6 +329,7 @@ export class VariantAnalysisManager
public async showView(variantAnalysisId: number): Promise<void> {
if (!this.variantAnalyses.get(variantAnalysisId)) {
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError`No variant analysis found with id: ${variantAnalysisId}.`,
);
}
@@ -347,6 +349,7 @@ export class VariantAnalysisManager
const variantAnalysis = await this.getVariantAnalysis(variantAnalysisId);
if (!variantAnalysis) {
void showAndLogWarningMessage(
extLogger,
"Could not open variant analysis query text. Variant analysis not found.",
);
return;
@@ -367,6 +370,7 @@ export class VariantAnalysisManager
await Window.showTextDocument(doc, { preview: false });
} catch (error) {
void showAndLogWarningMessage(
extLogger,
"Could not open variant analysis query text. Failed to open text document.",
);
}
@@ -377,6 +381,7 @@ export class VariantAnalysisManager
if (!variantAnalysis) {
void showAndLogWarningMessage(
extLogger,
"Could not open variant analysis query file",
);
return;
@@ -389,6 +394,7 @@ export class VariantAnalysisManager
await Window.showTextDocument(textDocument, ViewColumn.One);
} catch (error) {
void showAndLogWarningMessage(
extLogger,
`Could not open file: ${variantAnalysis.query.filePath}`,
);
}
@@ -701,6 +707,7 @@ export class VariantAnalysisManager
}
void showAndLogInformationMessage(
extLogger,
"Cancelling variant analysis. This may take a while.",
);
await cancelVariantAnalysis(this.app.credentials, variantAnalysis);

View File

@@ -98,7 +98,7 @@ export class VariantAnalysisMonitor extends DisposableObject {
if (lastErrorShown === errorMessage) {
void extLogger.log(message);
} else {
void showAndLogWarningMessage(message);
void showAndLogWarningMessage(extLogger, message);
lastErrorShown = errorMessage;
}

View File

@@ -166,6 +166,7 @@ export class VariantAnalysisView
break;
case "unhandledError":
void showAndLogExceptionWithTelemetry(
extLogger,
redactableError(
msg.error,
)`Unhandled error in variant analysis results view: ${msg.error.message}`,
@@ -186,7 +187,10 @@ export class VariantAnalysisView
);
if (!variantAnalysis) {
void showAndLogWarningMessage("Unable to load variant analysis");
void showAndLogWarningMessage(
extLogger,
"Unable to load variant analysis",
);
return;
}

View File

@@ -81,7 +81,7 @@ describe("Packaging commands", () => {
expect(showAndLogExceptionWithTelemetrySpy).toHaveBeenCalled();
expect(
showAndLogExceptionWithTelemetrySpy.mock.calls[0][0].fullMessage,
showAndLogExceptionWithTelemetrySpy.mock.calls[0][1].fullMessage,
).toEqual("Unable to download all packs. See log for more details.");
});