summaryrefslogtreecommitdiff
path: root/js/error_stack.ts
diff options
context:
space:
mode:
Diffstat (limited to 'js/error_stack.ts')
-rw-r--r--js/error_stack.ts273
1 files changed, 0 insertions, 273 deletions
diff --git a/js/error_stack.ts b/js/error_stack.ts
deleted file mode 100644
index 98b0b02d4..000000000
--- a/js/error_stack.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018-2019 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 dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-import { assert } from "./util.ts";
-
-export interface Location {
- /** The full url for the module, e.g. `file://some/file.ts` or
- * `https://some/file.ts`. */
- filename: string;
-
- /** The line number in the file. It is assumed to be 1-indexed. */
- line: number;
-
- /** The column number in the file. It is assumed to be 1-indexed. */
- column: number;
-}
-
-/** Given a current location in a module, lookup the source location and
- * return it.
- *
- * When Deno transpiles code, it keep source maps of the transpiled code. This
- * function can be used to lookup the original location. This is automatically
- * done when accessing the `.stack` of an error, or when an uncaught error is
- * logged. This function can be used to perform the lookup for creating better
- * error handling.
- *
- * **Note:** `line` and `column` are 1 indexed, which matches display
- * expectations, but is not typical of most index numbers in Deno.
- *
- * An example:
- *
- * const orig = Deno.applySourceMap({
- * location: "file://my/module.ts",
- * line: 5,
- * column: 15
- * });
- * console.log(`${orig.filename}:${orig.line}:${orig.column}`);
- *
- */
-export function applySourceMap(location: Location): Location {
- const { filename, line, column } = location;
- // On this side, line/column are 1 based, but in the source maps, they are
- // 0 based, so we have to convert back and forth
- const res = sendSync(dispatch.OP_APPLY_SOURCE_MAP, {
- filename,
- line: line - 1,
- column: column - 1
- });
- return {
- filename: res.filename,
- line: res.line + 1,
- column: res.column + 1
- };
-}
-
-/** Mutate the call site so that it returns the location, instead of its
- * original location.
- */
-function patchCallSite(callSite: CallSite, location: Location): CallSite {
- return {
- getThis(): unknown {
- return callSite.getThis();
- },
- getTypeName(): string {
- return callSite.getTypeName();
- },
- getFunction(): Function {
- return callSite.getFunction();
- },
- getFunctionName(): string {
- return callSite.getFunctionName();
- },
- getMethodName(): string {
- return callSite.getMethodName();
- },
- getFileName(): string {
- return location.filename;
- },
- getLineNumber(): number {
- return location.line;
- },
- getColumnNumber(): number {
- return location.column;
- },
- getEvalOrigin(): string | null {
- return callSite.getEvalOrigin();
- },
- isToplevel(): boolean {
- return callSite.isToplevel();
- },
- isEval(): boolean {
- return callSite.isEval();
- },
- isNative(): boolean {
- return callSite.isNative();
- },
- isConstructor(): boolean {
- return callSite.isConstructor();
- },
- isAsync(): boolean {
- return callSite.isAsync();
- },
- isPromiseAll(): boolean {
- return callSite.isPromiseAll();
- },
- getPromiseIndex(): number | null {
- return callSite.getPromiseIndex();
- }
- };
-}
-
-/** Return a string representations of a CallSite's method call name
- *
- * This is adapted directly from V8.
- */
-function getMethodCall(callSite: CallSite): string {
- let result = "";
-
- const typeName = callSite.getTypeName();
- const methodName = callSite.getMethodName();
- const functionName = callSite.getFunctionName();
-
- if (functionName) {
- if (typeName) {
- const startsWithTypeName = functionName.startsWith(typeName);
- if (!startsWithTypeName) {
- result += `${typeName}.`;
- }
- }
- result += functionName;
-
- if (methodName) {
- if (!functionName.endsWith(methodName)) {
- result += ` [as ${methodName}]`;
- }
- }
- } else {
- if (typeName) {
- result += `${typeName}.`;
- }
- if (methodName) {
- result += methodName;
- } else {
- result += "<anonymous>";
- }
- }
-
- return result;
-}
-
-/** Return a string representations of a CallSite's file location
- *
- * This is adapted directly from V8.
- */
-function getFileLocation(callSite: CallSite): string {
- if (callSite.isNative()) {
- return "native";
- }
-
- let result = "";
-
- const fileName = callSite.getFileName();
- if (!fileName && callSite.isEval()) {
- const evalOrigin = callSite.getEvalOrigin();
- assert(evalOrigin != null);
- result += `${evalOrigin}, `;
- }
-
- if (fileName) {
- result += fileName;
- } else {
- result += "<anonymous>";
- }
-
- const lineNumber = callSite.getLineNumber();
- if (lineNumber != null) {
- result += `:${lineNumber}`;
-
- const columnNumber = callSite.getColumnNumber();
- if (columnNumber != null) {
- result += `:${columnNumber}`;
- }
- }
-
- return result;
-}
-
-/** Convert a CallSite to a string.
- *
- * This is adapted directly from V8.
- */
-function callSiteToString(callSite: CallSite): string {
- 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) {
- result += "async ";
- }
- if (isPromiseAll) {
- result += `Promise.all (index ${callSite.getPromiseIndex})`;
- return result;
- }
- if (isMethodCall) {
- result += getMethodCall(callSite);
- } else if (isConstructor) {
- result += "new ";
- if (functionName) {
- result += functionName;
- } else {
- result += "<anonymous>";
- }
- } else if (functionName) {
- result += functionName;
- } else {
- result += getFileLocation(callSite);
- return result;
- }
-
- result += ` (${getFileLocation(callSite)})`;
- return result;
-}
-
-/** A replacement for the default stack trace preparer which will op into Rust
- * to apply source maps to individual sites
- */
-function prepareStackTrace(
- error: Error,
- structuredStackTrace: CallSite[]
-): string {
- return (
- `${error.name}: ${error.message}\n` +
- structuredStackTrace
- .map(
- (callSite): CallSite => {
- const filename = callSite.getFileName();
- const line = callSite.getLineNumber();
- const column = callSite.getColumnNumber();
- if (filename && line != null && column != null) {
- return patchCallSite(
- callSite,
- applySourceMap({
- filename,
- line,
- column
- })
- );
- }
- return callSite;
- }
- )
- .map((callSite): string => ` at ${callSiteToString(callSite)}`)
- .join("\n")
- );
-}
-
-/** Sets the `prepareStackTrace` method on the Error constructor which will
- * op into Rust to remap source code for caught errors where the `.stack` is
- * being accessed.
- *
- * See: https://v8.dev/docs/stack-trace-api
- */
-// @internal
-export function setPrepareStackTrace(ErrorConstructor: typeof Error): void {
- ErrorConstructor.prepareStackTrace = prepareStackTrace;
-}