mirror of
https://github.com/denoland/deno.git
synced 2025-08-02 18:12:39 +00:00
refactor(cli/fmt_errors): Format stack frames in prepareStackTrace() (#4706)
This commit is contained in:
parent
2feb661b85
commit
2b362bef85
25 changed files with 224 additions and 427 deletions
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
// Some of the code here is adapted directly from V8 and licensed under a BSD
|
||||
// style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8
|
||||
import * as colors from "./colors.ts";
|
||||
import { applySourceMap, Location } from "./ops/errors.ts";
|
||||
import { assert } from "./util.ts";
|
||||
import { exposeForTest } from "./internals.ts";
|
||||
|
@ -93,9 +94,12 @@ function getMethodCall(callSite: CallSite): string {
|
|||
return result;
|
||||
}
|
||||
|
||||
function getFileLocation(callSite: CallSite): string {
|
||||
function getFileLocation(callSite: CallSite, isInternal = false): string {
|
||||
const cyan = isInternal ? colors.gray : colors.cyan;
|
||||
const yellow = isInternal ? colors.gray : colors.yellow;
|
||||
const black = isInternal ? colors.gray : (s: string): string => s;
|
||||
if (callSite.isNative()) {
|
||||
return "native";
|
||||
return cyan("native");
|
||||
}
|
||||
|
||||
let result = "";
|
||||
|
@ -104,29 +108,32 @@ function getFileLocation(callSite: CallSite): string {
|
|||
if (!fileName && callSite.isEval()) {
|
||||
const evalOrigin = callSite.getEvalOrigin();
|
||||
assert(evalOrigin != null);
|
||||
result += `${evalOrigin}, `;
|
||||
result += cyan(`${evalOrigin}, `);
|
||||
}
|
||||
|
||||
if (fileName) {
|
||||
result += fileName;
|
||||
result += cyan(fileName);
|
||||
} else {
|
||||
result += "<anonymous>";
|
||||
result += cyan("<anonymous>");
|
||||
}
|
||||
|
||||
const lineNumber = callSite.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
result += `:${lineNumber}`;
|
||||
result += `${black(":")}${yellow(lineNumber.toString())}`;
|
||||
|
||||
const columnNumber = callSite.getColumnNumber();
|
||||
if (columnNumber != null) {
|
||||
result += `:${columnNumber}`;
|
||||
result += `${black(":")}${yellow(columnNumber.toString())}`;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function callSiteToString(callSite: CallSite): string {
|
||||
function callSiteToString(callSite: CallSite, isInternal = false): string {
|
||||
const cyan = isInternal ? colors.gray : colors.cyan;
|
||||
const black = isInternal ? colors.gray : (s: string): string => s;
|
||||
|
||||
let result = "";
|
||||
const functionName = callSite.getFunctionName();
|
||||
|
||||
|
@ -137,29 +144,33 @@ function callSiteToString(callSite: CallSite): string {
|
|||
const isMethodCall = !(isTopLevel || isConstructor);
|
||||
|
||||
if (isAsync) {
|
||||
result += "async ";
|
||||
result += colors.gray("async ");
|
||||
}
|
||||
if (isPromiseAll) {
|
||||
result += `Promise.all (index ${callSite.getPromiseIndex()})`;
|
||||
result += colors.bold(
|
||||
colors.italic(black(`Promise.all (index ${callSite.getPromiseIndex()})`))
|
||||
);
|
||||
return result;
|
||||
}
|
||||
if (isMethodCall) {
|
||||
result += getMethodCall(callSite);
|
||||
result += colors.bold(colors.italic(black(getMethodCall(callSite))));
|
||||
} else if (isConstructor) {
|
||||
result += "new ";
|
||||
result += colors.gray("new ");
|
||||
if (functionName) {
|
||||
result += functionName;
|
||||
result += colors.bold(colors.italic(black(functionName)));
|
||||
} else {
|
||||
result += "<anonymous>";
|
||||
result += cyan("<anonymous>");
|
||||
}
|
||||
} else if (functionName) {
|
||||
result += functionName;
|
||||
result += colors.bold(colors.italic(black(functionName)));
|
||||
} else {
|
||||
result += getFileLocation(callSite);
|
||||
result += getFileLocation(callSite, isInternal);
|
||||
return result;
|
||||
}
|
||||
|
||||
result += ` (${getFileLocation(callSite)})`;
|
||||
result += ` ${black("(")}${getFileLocation(callSite, isInternal)}${black(
|
||||
")"
|
||||
)}`;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -207,7 +218,10 @@ function prepareStackTrace(
|
|||
error: Error,
|
||||
structuredStackTrace: CallSite[]
|
||||
): string {
|
||||
Object.defineProperty(error, "__callSiteEvals", { value: [] });
|
||||
Object.defineProperties(error, {
|
||||
__callSiteEvals: { value: [] },
|
||||
__formattedFrames: { value: [] },
|
||||
});
|
||||
const errorString =
|
||||
`${error.name}: ${error.message}\n` +
|
||||
structuredStackTrace
|
||||
|
@ -230,16 +244,23 @@ function prepareStackTrace(
|
|||
}
|
||||
)
|
||||
.map((callSite): string => {
|
||||
const isInternal =
|
||||
callSite.getFileName()?.startsWith("$deno$") ?? false;
|
||||
const string = callSiteToString(callSite, isInternal);
|
||||
const callSiteEv = Object.freeze(evaluateCallSite(callSite));
|
||||
if (callSiteEv.lineNumber != null && callSiteEv.columnNumber != null) {
|
||||
// @ts-ignore
|
||||
error["__callSiteEvals"].push(callSiteEv);
|
||||
error.__callSiteEvals.push(callSiteEv);
|
||||
// @ts-ignore
|
||||
error.__formattedFrames.push(string);
|
||||
}
|
||||
return ` at ${callSiteToString(callSite)}`;
|
||||
return ` at ${colors.stripColor(string)}`;
|
||||
})
|
||||
.join("\n");
|
||||
// @ts-ignore
|
||||
Object.freeze(error["__callSiteEvals"]);
|
||||
Object.freeze(error.__callSiteEvals);
|
||||
// @ts-ignore
|
||||
Object.freeze(error.__formattedFrames);
|
||||
return errorString;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue