or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-stack-trace

Get v8 stack traces as an array of CallSite objects.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/stack-trace@0.0.x

To install, run

npx @tessl/cli install tessl/npm-stack-trace@0.0.0

index.mddocs/

Stack Trace

Stack Trace is a Node.js library that provides utilities for capturing and parsing V8 stack traces as arrays of CallSite objects. It offers two main functions: capturing current stack traces using V8's native stack trace API, and parsing existing Error objects' stack properties using regex-based parsing.

Package Information

  • Package Name: stack-trace
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install stack-trace

Core Imports

const stackTrace = require("stack-trace");

Destructured import:

const { get, parse } = require("stack-trace");

Basic Usage

const stackTrace = require("stack-trace");

// Capture current stack trace
const trace = stackTrace.get();
console.log(trace[0].getFileName()); // Current file name
console.log(trace[0].getFunctionName()); // Current function name

// Parse existing error stack
const err = new Error("something went wrong");
const parsedTrace = stackTrace.parse(err);
console.log(parsedTrace[0].getFileName()); // Error file name

Architecture

Stack Trace is built around two complementary approaches for accessing V8 stack trace information:

  • Native V8 Integration: The get() function uses V8's Error.prepareStackTrace and Error.captureStackTrace APIs to capture live stack traces with full CallSite object support
  • Regex-based Parsing: The parse() function analyzes Error stack strings using regular expressions to extract stack frame information when native access isn't available
  • CallSite Factory Pattern: Internal CallSite constructor and _createParsedCallSite() factory provide consistent object interface regardless of data source
  • Cross-boundary Support: Integration with long-stack-traces module enables stack trace continuity across asynchronous boundaries
  • Graceful Degradation: Robust error handling ensures the library works even with malformed or incomplete stack data

Capabilities

Stack Trace Capture

Captures the current execution stack as an array of CallSite objects using V8's native stack trace API.

/**
 * Captures current stack trace as array of CallSite objects
 * @param {Function} [belowFn] - Optional function to exclude from trace
 * @returns {CallSite[]} Array of CallSite objects representing the stack
 */
function get(belowFn);

Usage Examples:

const stackTrace = require("stack-trace");

// Get full stack trace
function myFunction() {
  const trace = stackTrace.get();
  console.log("Called from:", trace[1].getFunctionName());
}

// Get stack trace excluding current function
function excludeMe() {
  const trace = stackTrace.get(excludeMe);
  // trace[0] will be the caller of excludeMe, not excludeMe itself
  console.log("Real caller:", trace[0].getFunctionName());
}

Stack Trace Parsing

Parses an Error object's stack property into an array of CallSite-compatible objects using regex-based parsing.

/**
 * Parses Error object's stack property into array of CallSite objects
 * @param {Error|Object} err - Error object or object with stack property
 * @returns {CallSite[]} Array of CallSite objects, empty array if no stack
 */
function parse(err);

Usage Examples:

const stackTrace = require("stack-trace");

// Parse error stack trace
try {
  throw new Error("Oops!");
} catch (err) {
  const trace = stackTrace.parse(err);
  trace.forEach((site, i) => {
    console.log(`${i}: ${site.getFunctionName()} at ${site.getFileName()}:${site.getLineNumber()}`);
  });
}

// Handle malformed stacks gracefully
const badError = { stack: "corrupted\nstack\ntrace" };
const trace = stackTrace.parse(badError); // Returns filtered, valid entries only

// Handle missing stack property
const noStack = {};
const emptyTrace = stackTrace.parse(noStack); // Returns []

CallSite Objects

The CallSite objects returned by both get() and parse() implement the V8 CallSite API with methods for accessing stack frame information.

/**
 * CallSite object representing a single frame in the stack trace
 */
interface CallSite {
  /** Returns the value of this */
  getThis(): any;
  /** Returns the type name of this as a string */
  getTypeName(): string | null;
  /** Returns the current function */
  getFunction(): Function | null;
  /** Returns the name of the current function */
  getFunctionName(): string | null;
  /** Returns the name of the property holding the current function */
  getMethodName(): string | null;
  /** Returns the name of the script file */
  getFileName(): string | null;
  /** Returns the current line number */
  getLineNumber(): number | null;
  /** Returns the current column number */
  getColumnNumber(): number | null;
  /** Returns eval origin if created using eval */
  getEvalOrigin(): string | null;
  /** Returns true if this is a top-level invocation */
  isTopLevel(): boolean;
  /** Returns true if this call takes place in eval code */
  isEval(): boolean;
  /** Returns true if this call is in native V8 code */
  isNative(): boolean;
  /** Returns true if this is a constructor call */
  isConstructor(): boolean;
}

Important Notes:

  • Full API Support: get() returns CallSite objects with full V8 API support
  • Limited API Support: parse() returns objects with limited method support:
    • Reliable: getTypeName(), getFunctionName(), getMethodName(), getFileName(), getLineNumber(), getColumnNumber(), isNative()
    • May return null: getThis(), getFunction(), getEvalOrigin(), isTopLevel(), isEval(), isConstructor()

Usage Examples:

const stackTrace = require("stack-trace");

function analyzeStack() {
  const trace = stackTrace.get();
  const currentFrame = trace[0];
  
  console.log("Function:", currentFrame.getFunctionName());
  console.log("File:", currentFrame.getFileName());
  console.log("Line:", currentFrame.getLineNumber());
  console.log("Column:", currentFrame.getColumnNumber());
  console.log("Is native:", currentFrame.isNative());
  console.log("Is constructor:", currentFrame.isConstructor());
}

// Analyze parsed error stack
try {
  someFunction();
} catch (err) {
  const trace = stackTrace.parse(err);
  trace.forEach(frame => {
    if (frame.isNative()) {
      console.log("Native call:", frame.getFunctionName());
    } else {
      console.log(`${frame.getFunctionName()} at ${frame.getFileName()}:${frame.getLineNumber()}`);
    }
  });
}

Advanced Features

Long Stack Traces Integration

Stack Trace is compatible with the long-stack-traces module for cross-event-loop boundary tracing.

require("long-stack-traces");
const stackTrace = require("stack-trace");

setTimeout(() => {
  const err = new Error("Async error");
  const trace = stackTrace.parse(err);
  
  // Event loop boundary markers appear as special CallSite objects
  trace.forEach(frame => {
    if (frame.getFileName() === "----------------------------------------") {
      console.log("Event loop boundary detected");
    }
  });
}, 100);

Error Handling and Edge Cases

The library handles various edge cases gracefully:

  • Missing stack property: Returns empty array
  • Corrupted stack traces: Filters out unparseable lines
  • Native function calls: Properly identifies with isNative() returning true
  • Anonymous functions: Handles anonymous function detection
  • Complex function names: Parses object methods, nested scopes, and module boundaries

Internal API

_createParsedCallSite

Internal utility function for creating CallSite objects from parsed properties.

/**
 * Internal factory function for creating CallSite objects
 * @param {Object} properties - Properties object for CallSite creation
 * @returns {CallSite} CallSite instance with specified properties
 */
function _createParsedCallSite(properties);

Note: While exported, this function is primarily for internal use and testing. Normal usage should rely on get() and parse() methods.