mirror of
https://github.com/denoland/deno.git
synced 2024-12-11 18:17:48 -05:00
refactor(core/error): use evaluated call sites for formatting (#15369)
This commit is contained in:
parent
b50088c247
commit
5ceaecbae4
2 changed files with 49 additions and 136 deletions
|
@ -17,6 +17,7 @@
|
|||
Promise,
|
||||
ObjectFromEntries,
|
||||
MapPrototypeGet,
|
||||
MapPrototypeHas,
|
||||
MapPrototypeDelete,
|
||||
MapPrototypeSet,
|
||||
PromisePrototypeThen,
|
||||
|
|
184
core/02_error.js
184
core/02_error.js
|
@ -15,156 +15,81 @@
|
|||
ArrayPrototypeJoin,
|
||||
} = window.__bootstrap.primordials;
|
||||
|
||||
// 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
|
||||
function patchCallSite(callSite, location) {
|
||||
return {
|
||||
getThis() {
|
||||
return callSite.getThis();
|
||||
},
|
||||
getTypeName() {
|
||||
return callSite.getTypeName();
|
||||
},
|
||||
getFunction() {
|
||||
return callSite.getFunction();
|
||||
},
|
||||
getFunctionName() {
|
||||
return callSite.getFunctionName();
|
||||
},
|
||||
getMethodName() {
|
||||
return callSite.getMethodName();
|
||||
},
|
||||
getFileName() {
|
||||
return location.fileName;
|
||||
},
|
||||
getLineNumber() {
|
||||
return location.lineNumber;
|
||||
},
|
||||
getColumnNumber() {
|
||||
return location.columnNumber;
|
||||
},
|
||||
getEvalOrigin() {
|
||||
return callSite.getEvalOrigin();
|
||||
},
|
||||
isToplevel() {
|
||||
return callSite.isToplevel();
|
||||
},
|
||||
isEval() {
|
||||
return callSite.isEval();
|
||||
},
|
||||
isNative() {
|
||||
return callSite.isNative();
|
||||
},
|
||||
isConstructor() {
|
||||
return callSite.isConstructor();
|
||||
},
|
||||
isAsync() {
|
||||
return callSite.isAsync();
|
||||
},
|
||||
isPromiseAll() {
|
||||
return callSite.isPromiseAll();
|
||||
},
|
||||
getPromiseIndex() {
|
||||
return callSite.getPromiseIndex();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Keep in sync with `cli/fmt_errors.rs`.
|
||||
function formatLocation(callSite) {
|
||||
if (callSite.isNative()) {
|
||||
function formatLocation(cse) {
|
||||
if (cse.isNative) {
|
||||
return "native";
|
||||
}
|
||||
|
||||
let result = "";
|
||||
|
||||
const fileName = callSite.getFileName();
|
||||
|
||||
if (fileName) {
|
||||
result += core.opSync("op_format_file_name", fileName);
|
||||
if (cse.fileName) {
|
||||
result += core.opSync("op_format_file_name", cse.fileName);
|
||||
} else {
|
||||
if (callSite.isEval()) {
|
||||
const evalOrigin = callSite.getEvalOrigin();
|
||||
if (evalOrigin == null) {
|
||||
if (cse.isEval) {
|
||||
if (cse.evalOrigin == null) {
|
||||
throw new Error("assert evalOrigin");
|
||||
}
|
||||
result += `${evalOrigin}, `;
|
||||
result += `${cse.evalOrigin}, `;
|
||||
}
|
||||
result += "<anonymous>";
|
||||
}
|
||||
|
||||
const lineNumber = callSite.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
result += `:${lineNumber}`;
|
||||
|
||||
const columnNumber = callSite.getColumnNumber();
|
||||
if (columnNumber != null) {
|
||||
result += `:${columnNumber}`;
|
||||
if (cse.lineNumber != null) {
|
||||
result += `:${cse.lineNumber}`;
|
||||
if (cse.columnNumber != null) {
|
||||
result += `:${cse.columnNumber}`;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Keep in sync with `cli/fmt_errors.rs`.
|
||||
function formatCallSite(callSite) {
|
||||
function formatCallSiteEval(cse) {
|
||||
let result = "";
|
||||
const functionName = callSite.getFunctionName();
|
||||
|
||||
const isTopLevel = callSite.isToplevel();
|
||||
const isAsync = callSite.isAsync();
|
||||
const isPromiseAll = callSite.isPromiseAll();
|
||||
const isConstructor = callSite.isConstructor();
|
||||
const isMethodCall = !(isTopLevel || isConstructor);
|
||||
|
||||
if (isAsync) {
|
||||
if (cse.isAsync) {
|
||||
result += "async ";
|
||||
}
|
||||
if (isPromiseAll) {
|
||||
result += `Promise.all (index ${callSite.getPromiseIndex()})`;
|
||||
if (cse.isPromiseAll) {
|
||||
result += `Promise.all (index ${cse.promiseIndex})`;
|
||||
return result;
|
||||
}
|
||||
const isMethodCall = !(cse.isToplevel || cse.isConstructor);
|
||||
if (isMethodCall) {
|
||||
const typeName = callSite.getTypeName();
|
||||
const methodName = callSite.getMethodName();
|
||||
|
||||
if (functionName) {
|
||||
if (typeName) {
|
||||
if (!StringPrototypeStartsWith(functionName, typeName)) {
|
||||
result += `${typeName}.`;
|
||||
if (cse.functionName) {
|
||||
if (cse.typeName) {
|
||||
if (!StringPrototypeStartsWith(cse.functionName, cse.typeName)) {
|
||||
result += `${cse.typeName}.`;
|
||||
}
|
||||
}
|
||||
result += functionName;
|
||||
if (methodName) {
|
||||
if (!StringPrototypeEndsWith(functionName, methodName)) {
|
||||
result += ` [as ${methodName}]`;
|
||||
result += cse.functionName;
|
||||
if (cse.methodName) {
|
||||
if (!StringPrototypeEndsWith(cse.functionName, cse.methodName)) {
|
||||
result += ` [as ${cse.methodName}]`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (typeName) {
|
||||
result += `${typeName}.`;
|
||||
if (cse.typeName) {
|
||||
result += `${cse.typeName}.`;
|
||||
}
|
||||
if (methodName) {
|
||||
result += methodName;
|
||||
if (cse.methodName) {
|
||||
result += cse.methodName;
|
||||
} else {
|
||||
result += "<anonymous>";
|
||||
}
|
||||
}
|
||||
} else if (isConstructor) {
|
||||
} else if (cse.isConstructor) {
|
||||
result += "new ";
|
||||
if (functionName) {
|
||||
result += functionName;
|
||||
if (cse.functionName) {
|
||||
result += cse.functionName;
|
||||
} else {
|
||||
result += "<anonymous>";
|
||||
}
|
||||
} else if (functionName) {
|
||||
result += functionName;
|
||||
} else if (cse.functionName) {
|
||||
result += cse.functionName;
|
||||
} else {
|
||||
result += formatLocation(callSite);
|
||||
result += formatLocation(cse);
|
||||
return result;
|
||||
}
|
||||
|
||||
result += ` (${formatLocation(callSite)})`;
|
||||
result += ` (${formatLocation(cse)})`;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -189,37 +114,24 @@
|
|||
};
|
||||
}
|
||||
|
||||
/** A function that can be used as `Error.prepareStackTrace`. */
|
||||
function prepareStackTrace(
|
||||
error,
|
||||
callSites,
|
||||
) {
|
||||
const mappedCallSites = ArrayPrototypeMap(callSites, (callSite) => {
|
||||
const fileName = callSite.getFileName();
|
||||
const lineNumber = callSite.getLineNumber();
|
||||
const columnNumber = callSite.getColumnNumber();
|
||||
if (fileName && lineNumber != null && columnNumber != null) {
|
||||
return patchCallSite(
|
||||
callSite,
|
||||
core.opSync("op_apply_source_map", {
|
||||
fileName,
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
}),
|
||||
);
|
||||
function sourceMapCallSiteEval(cse) {
|
||||
if (cse.fileName && cse.lineNumber != null && cse.columnNumber != null) {
|
||||
return { ...cse, ...core.opSync("op_apply_source_map", cse) };
|
||||
}
|
||||
return callSite;
|
||||
});
|
||||
return cse;
|
||||
}
|
||||
|
||||
/** A function that can be used as `Error.prepareStackTrace`. */
|
||||
function prepareStackTrace(error, callSites) {
|
||||
let callSiteEvals = ArrayPrototypeMap(callSites, evaluateCallSite);
|
||||
callSiteEvals = ArrayPrototypeMap(callSiteEvals, sourceMapCallSiteEval);
|
||||
ObjectDefineProperties(error, {
|
||||
__callSiteEvals: { value: [], configurable: true },
|
||||
});
|
||||
const formattedCallSites = [];
|
||||
for (const callSite of mappedCallSites) {
|
||||
ArrayPrototypePush(error.__callSiteEvals, evaluateCallSite(callSite));
|
||||
ArrayPrototypePush(
|
||||
formattedCallSites,
|
||||
formatCallSite(callSite),
|
||||
);
|
||||
for (const cse of callSiteEvals) {
|
||||
ArrayPrototypePush(error.__callSiteEvals, cse);
|
||||
ArrayPrototypePush(formattedCallSites, formatCallSiteEval(cse));
|
||||
}
|
||||
const message = error.message !== undefined ? error.message : "";
|
||||
const name = error.name !== undefined ? error.name : "Error";
|
||||
|
|
Loading…
Reference in a new issue