Created
August 19, 2022 16:03
-
-
Save bryophyta/049a5c9cac27d9c77e7acfe2e26c57b8 to your computer and use it in GitHub Desktop.
Experiment: Stack traces with TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// `CallSite` is the class representing a stack frame in the V8 spec | |
// (see https://v8.dev/docs/stack-trace-api#customizing-stack-traces) | |
// hat tip to the callsites package, where I'm importing the `CallSite` type from: https://github.com/sindresorhus/callsites | |
import { CallSite } from "https://raw.githubusercontent.com/sindresorhus/callsites/7fb22a67645ea741cc016937e8f3662eb533eb6e/index.d.ts"; | |
// there is a default implementation for preparing stack traces on the Error object, but TypeScript doesn't recognise | |
// this. (maybe because it's not present in all runtimes? or maybe the default is initialised in some other way?) | |
type ErrorWithPrepFn = ErrorConstructor & { prepareStackTrace?: (error: Error, stack: CallSite[]) => unknown} | |
// definitions | |
function inner() { | |
console.log("Stack from inside `inner()`:") | |
console.log(new Error("").stack) | |
} | |
function outer() { | |
inner() | |
} | |
function outermost() { | |
outer() | |
} | |
function outsideEntirely() { | |
console.log("I'm running now, so `outsideEntirely` won't appear in the stack trace.") | |
} | |
function run() { | |
outsideEntirely(); | |
outermost(); | |
} | |
// define a handler to assign to `Error.prepareStackTrace` | |
function returnFunctionNames(_: Error, stack: CallSite[]) { | |
return stack.map(call => call.getFunctionName()); | |
} | |
// here we assign our custom handler; when an error is thrown, | |
// this method will be called with the error and the call stack at the time | |
// the error arose | |
(Error as ErrorWithPrepFn).prepareStackTrace = returnFunctionNames | |
/** | |
* run code | |
* expected output: | |
> I'm running now, so I won't appear in the stack trace. | |
> Stack from inside `inner()`: | |
> [ "inner", "outer", "outermost", "run", null ] | |
*/ | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I wrote this to run in Deno.