Skip to content

Instantly share code, notes, and snippets.

@bryophyta
Created August 19, 2022 16:03
Show Gist options
  • Save bryophyta/049a5c9cac27d9c77e7acfe2e26c57b8 to your computer and use it in GitHub Desktop.
Save bryophyta/049a5c9cac27d9c77e7acfe2e26c57b8 to your computer and use it in GitHub Desktop.
Experiment: Stack traces with TypeScript
// `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()
@bryophyta
Copy link
Author

I wrote this to run in Deno.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment