Merge pull request #3004 from github/koesie10/redactable-error-stack
Show stack for redactable error in log
This commit is contained in:
Коммит
41aeb47a4e
|
@ -22,6 +22,14 @@ export class RedactableError extends Error {
|
||||||
.join("");
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get fullMessageWithStack(): string {
|
||||||
|
if (!this.stack) {
|
||||||
|
return this.fullMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${this.fullMessage}\n${this.stack}`;
|
||||||
|
}
|
||||||
|
|
||||||
public get redactedMessage(): string {
|
public get redactedMessage(): string {
|
||||||
return this.strings
|
return this.strings
|
||||||
.map((s, i) => s + (this.hasValue(i) ? this.getRedactedValue(i) : ""))
|
.map((s, i) => s + (this.hasValue(i) ? this.getRedactedValue(i) : ""))
|
||||||
|
|
|
@ -112,5 +112,5 @@ export async function showAndLogExceptionWithTelemetry(
|
||||||
options: ShowAndLogExceptionOptions = {},
|
options: ShowAndLogExceptionOptions = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
telemetry?.sendError(error, options.extraTelemetryProperties);
|
telemetry?.sendError(error, options.extraTelemetryProperties);
|
||||||
return showAndLogErrorMessage(logger, error.fullMessage, options);
|
return showAndLogErrorMessage(logger, error.fullMessageWithStack, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,7 @@ import {
|
||||||
showAndLogExceptionWithTelemetry,
|
showAndLogExceptionWithTelemetry,
|
||||||
} from "../logging";
|
} from "../logging";
|
||||||
import { extLogger } from "../logging/vscode";
|
import { extLogger } from "../logging/vscode";
|
||||||
import {
|
import { asError, getErrorMessage } from "../../common/helpers-pure";
|
||||||
asError,
|
|
||||||
getErrorMessage,
|
|
||||||
getErrorStack,
|
|
||||||
} from "../../common/helpers-pure";
|
|
||||||
import { redactableError } from "../../common/errors";
|
import { redactableError } from "../../common/errors";
|
||||||
import { UserCancellationException } from "./progress";
|
import { UserCancellationException } from "./progress";
|
||||||
import { telemetryListener } from "./telemetry";
|
import { telemetryListener } from "./telemetry";
|
||||||
|
@ -66,10 +62,7 @@ export function registerCommandWithErrorHandling(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Include the full stack in the error log only.
|
// Include the full stack in the error log only.
|
||||||
const errorStack = getErrorStack(e);
|
const fullMessage = errorMessage.fullMessageWithStack;
|
||||||
const fullMessage = errorStack
|
|
||||||
? `${errorMessage.fullMessage}\n${errorStack}`
|
|
||||||
: errorMessage.fullMessage;
|
|
||||||
void showAndLogExceptionWithTelemetry(logger, telemetry, errorMessage, {
|
void showAndLogExceptionWithTelemetry(logger, telemetry, errorMessage, {
|
||||||
fullMessage,
|
fullMessage,
|
||||||
extraTelemetryProperties: {
|
extraTelemetryProperties: {
|
||||||
|
|
|
@ -1170,10 +1170,7 @@ function addUnhandledRejectionListener() {
|
||||||
const message = redactableError(
|
const message = redactableError(
|
||||||
asError(error),
|
asError(error),
|
||||||
)`Unhandled error: ${getErrorMessage(error)}`;
|
)`Unhandled error: ${getErrorMessage(error)}`;
|
||||||
const stack = getErrorStack(error);
|
const fullMessage = message.fullMessageWithStack;
|
||||||
const fullMessage = stack
|
|
||||||
? `Unhandled error: ${stack}`
|
|
||||||
: message.fullMessage;
|
|
||||||
|
|
||||||
// Add a catch so that showAndLogExceptionWithTelemetry fails, we avoid
|
// Add a catch so that showAndLogExceptionWithTelemetry fails, we avoid
|
||||||
// triggering "unhandledRejection" and avoid an infinite loop
|
// triggering "unhandledRejection" and avoid an infinite loop
|
||||||
|
|
|
@ -441,7 +441,6 @@ export async function compileAndRunQueryAgainstDatabaseCore(
|
||||||
const error = result.message
|
const error = result.message
|
||||||
? redactableError`${result.message}`
|
? redactableError`${result.message}`
|
||||||
: redactableError`Failed to run query`;
|
: redactableError`Failed to run query`;
|
||||||
void extLogger.log(error.fullMessage);
|
|
||||||
void showAndLogExceptionWithTelemetry(
|
void showAndLogExceptionWithTelemetry(
|
||||||
extLogger,
|
extLogger,
|
||||||
telemetryListener,
|
telemetryListener,
|
||||||
|
|
|
@ -19,6 +19,40 @@ describe("errorMessage", () => {
|
||||||
).toEqual("Failed to create database foo");
|
).toEqual("Failed to create database foo");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("fullMessageWithStack includes the stack", () => {
|
||||||
|
expect(
|
||||||
|
redactableError`Failed to create database ${"foo"}`.fullMessageWithStack,
|
||||||
|
).toMatch(
|
||||||
|
/^Failed to create database foo\nError: Failed to create database foo\n +at redactableError \(/,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fullMessageWithStack includes the cause stack for given error", () => {
|
||||||
|
function myRealFunction() {
|
||||||
|
throw new Error("Internal error");
|
||||||
|
}
|
||||||
|
|
||||||
|
let error: Error;
|
||||||
|
try {
|
||||||
|
myRealFunction();
|
||||||
|
|
||||||
|
fail("Expected an error to be thrown");
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (!(e instanceof Error)) {
|
||||||
|
throw new Error("Expected an Error to be thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(
|
||||||
|
redactableError(error)`Failed to create database ${"foo"}`
|
||||||
|
.fullMessageWithStack,
|
||||||
|
).toMatch(
|
||||||
|
/^Failed to create database foo\nError: Internal error\n +at myRealFunction \(/,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("redactedMessage redacts the given message", () => {
|
it("redactedMessage redacts the given message", () => {
|
||||||
expect(
|
expect(
|
||||||
redactableError`Failed to create database ${"foo"}`.redactedMessage,
|
redactableError`Failed to create database ${"foo"}`.redactedMessage,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче