or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-stacktrace-js

Framework-agnostic micro-library for generating, parsing, and enhancing JavaScript stack traces in all environments

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/stacktrace-js@2.0.x

To install, run

npx @tessl/cli install tessl/npm-stacktrace-js@2.0.0

index.mddocs/

StackTrace.js

StackTrace.js is a framework-agnostic micro-library for generating, parsing, and enhancing JavaScript stack traces in all environments. It provides cross-browser compatible stack trace generation with source map support, Promise-based asynchronous APIs, and function instrumentation capabilities for debugging and error reporting.

Package Information

  • Package Name: stacktrace-js
  • Package Type: npm
  • Language: JavaScript (with TypeScript definitions)
  • Installation:
    • npm: npm install stacktrace-js
    • bower: bower install stacktrace-js
    • CDN: https://cdnjs.com/libraries/stacktrace.js

Core Imports

import StackTrace from "stacktrace-js";

For CommonJS:

const StackTrace = require("stacktrace-js");

Browser (global):

// Available as window.StackTrace after including the script

UMD (AMD):

define(['stacktrace'], function(StackTrace) {
  // Use StackTrace here
});

Basic Usage

import StackTrace from "stacktrace-js";

// Get current stack trace
StackTrace.get()
  .then(stackframes => {
    stackframes.forEach(frame => {
      console.log(frame.toString());
    });
  })
  .catch(err => console.error(err));

// Parse an error object
try {
  throw new Error("Something went wrong!");
} catch (error) {
  StackTrace.fromError(error)
    .then(stackframes => {
      console.log("Stack trace:", stackframes);
    });
}

Architecture

StackTrace.js is built around several key components:

  • Stack Generation: Multiple strategies for capturing stack traces (Error.stack, artificial generation)
  • Stack Parsing: Integration with error-stack-parser for cross-browser stack trace parsing
  • Source Enhancement: Uses stacktrace-gps for source map resolution and function name guessing
  • Promise-based API: Asynchronous operations return Promises for enhanced stack frames
  • Synchronous Fallback: getSync() method for immediate results without source map enhancement
  • Function Instrumentation: Capability to wrap functions for automatic stack trace capture
  • Network Reporting: Built-in error reporting to remote endpoints

Capabilities

Stack Trace Generation

Core functionality for capturing stack traces from various sources with optional source map enhancement.

/**
 * Get a backtrace from invocation point with source map enhancement
 * @param options - Optional configuration object
 * @returns Promise resolving to Array of StackFrame objects
 */
function get(options?: StackTraceOptions): Promise<StackFrame[]>;

/**
 * Get a backtrace synchronously (no source maps or function name guessing)
 * @param options - Optional configuration object
 * @returns Array of StackFrame objects
 */
function getSync(options?: StackTraceOptions): StackFrame[];

Usage Examples:

// Asynchronous with source map enhancement
StackTrace.get({
  filter: frame => !frame.functionName?.includes('internal'),
  offline: false
}).then(stackframes => {
  console.log('Enhanced stack trace:', stackframes);
});

// Synchronous (faster, less detailed)
const frames = StackTrace.getSync({
  filter: frame => frame.fileName?.includes('my-app')
});
console.log('Sync stack trace:', frames);

Error Stack Parsing

Parse existing Error objects and enhance them with source maps and location information.

/**
 * Parse Error object and enhance with source maps
 * @param error - Error object to parse
 * @param options - Optional configuration object
 * @returns Promise resolving to Array of StackFrame objects
 */
function fromError(error: Error, options?: StackTraceOptions): Promise<StackFrame[]>;

Usage Examples:

// Parse caught errors
window.onerror = function(msg, file, line, col, error) {
  StackTrace.fromError(error, {
    sourceCache: {
      'http://example.com/script.js': cachedSource
    }
  }).then(stackframes => {
    // Send to error reporting service
    reportError(msg, stackframes);
  });
};

// Parse custom errors
const customError = new Error("Custom error");
StackTrace.fromError(customError).then(frames => {
  console.log("Parsed error stack:", frames);
});

Artificial Stack Generation

Generate stack traces by walking the call chain when Error.stack is not available.

/**
 * Generate backtrace by walking arguments.callee.caller chain
 * @param options - Optional configuration object
 * @returns Promise resolving to Array of StackFrame objects
 */
function generateArtificially(options?: StackTraceOptions): Promise<StackFrame[]>;

Usage Examples:

// Fallback for environments without Error.stack
StackTrace.generateArtificially({
  filter: frame => frame.functionName !== 'anonymous'
}).then(stackframes => {
  console.log("Artificial stack trace:", stackframes);
});

Function Instrumentation

Wrap functions to automatically capture stack traces on invocation for debugging and profiling.

/**
 * Wrap function to trigger callback with stack trace on each invocation
 * @param fn - Function to instrument
 * @param callback - Function called with stack trace array
 * @param errback - Optional error callback function
 * @param thisArg - Optional context object
 * @returns Instrumented function
 * @throws Error if fn is not a function
 */
function instrument<TFunc extends Function>(
  fn: TFunc,
  callback: (stackFrames: StackFrame[]) => void,
  errback?: (error: Error) => void,
  thisArg?: any
): TFunc;

/**
 * Revert instrumented function to original state
 * @param fn - Instrumented function to revert
 * @returns Original (non-instrumented) function
 * @throws Error if fn is not a function
 */
function deinstrument<TFunc extends Function>(fn: TFunc): TFunc;

Usage Examples:

// Instrument a function for debugging
function processData(data) {
  return data.map(item => item * 2);
}

const instrumentedProcess = StackTrace.instrument(
  processData,
  stackframes => {
    console.log("processData called from:", stackframes[0]);
  },
  error => console.error("Failed to get stack trace:", error)
);

// Use the instrumented function
const result = instrumentedProcess([1, 2, 3]);

// Restore original function
const originalProcess = StackTrace.deinstrument(instrumentedProcess);

Error Reporting

Submit stack trace data to remote endpoints for centralized error tracking.

/**
 * Serialize stackframes and POST to given URL
 * @param stackframes - Array of StackFrame objects
 * @param url - Target URL for POST request
 * @param errorMsg - Optional error message string
 * @param requestOptions - Optional HTTP request options (headers supported)
 * @returns Promise resolving to response text
 */
function report(
  stackframes: StackFrame[],
  url: string,
  errorMsg?: string,
  requestOptions?: object
): Promise<any>;

Usage Examples:

// Report errors to monitoring service
StackTrace.get().then(stackframes => {
  return StackTrace.report(
    stackframes,
    'https://api.errorservice.com/errors',
    'Unhandled exception occurred',
    {
      headers: {
        'Authorization': 'Bearer token123',
        'Content-Type': 'application/json'
      }
    }
  );
}).then(response => {
  console.log("Error reported successfully:", response);
});

Types

interface StackTraceOptions {
  /** Filter function for stack frames */
  filter?: (stackFrame: StackFrame) => boolean;
  /** Pre-populated source cache to avoid network requests */
  sourceCache?: SourceCache;
  /** Set to true to prevent all network requests */
  offline?: boolean;
}

interface SourceCache {
  [url: string]: string | Promise<string>;
}

interface StackFrame {
  /** Whether frame is constructor call */
  isConstructor?: boolean;
  /** Whether frame is from eval */
  isEval?: boolean;
  /** Whether frame is native code */
  isNative?: boolean;
  /** Whether frame is top-level */
  isTopLevel?: boolean;
  /** Column number in source */
  columnNumber?: number;
  /** Line number in source */
  lineNumber?: number;
  /** Source file name/URL */
  fileName?: string;
  /** Function name */
  functionName?: string;
  /** Source code line */
  source?: string;
  /** Function arguments */
  args?: any[];
  /** Origin frame for eval */
  evalOrigin?: StackFrame;

  /** Get/set methods for all properties */
  getIsConstructor(): boolean;
  setIsConstructor(): void;
  getIsEval(): boolean;
  setIsEval(): void;
  getIsNative(): boolean;
  setIsNative(): void;
  getIsTopLevel(): boolean;
  setIsTopLevel(): void;
  getColumnNumber(): number;
  setColumnNumber(): void;
  getLineNumber(): number;
  setLineNumber(): void;
  getFileName(): string;
  setFileName(): void;
  getFunctionName(): string;
  setFunctionName(): void;
  getSource(): string;
  setSource(): void;
  getArgs(): any[];
  setArgs(): void;
  getEvalOrigin(): StackFrame;
  setEvalOrigin(): void;
  
  /** String representation */
  toString(): string;
}

Error Handling

StackTrace.js includes built-in error handling patterns:

  • Promise Rejection: All async methods return Promises that reject on errors
  • Fallback Strategies: Automatically falls back to artificial generation when Error.stack unavailable
  • Silent Failures: Instrumentation fails silently while still calling the original function
  • Network Errors: Report function handles HTTP error responses and network failures

Common error scenarios:

// Automatic error handling with window.onerror
window.onerror = function(msg, file, line, col, error) {
  StackTrace.fromError(error).then(stackframes => {
    console.log('Error stack trace:', stackframes);
    // Send to error reporting service
  }).catch(err => {
    console.log('Failed to parse error:', err.message);
  });
};

// Handle parsing failures
StackTrace.fromError(malformedError)
  .catch(err => {
    console.log("Failed to parse error:", err.message);
    // Fallback to artificial generation
    return StackTrace.generateArtificially();
  });

// Handle network failures in reporting
StackTrace.report(frames, 'https://unreachable.com/api')
  .catch(err => {
    console.log("Failed to report error:", err.message);
    // Could fallback to local storage or console logging
  });

Browser Compatibility

  • Modern Browsers: Full functionality including source maps
  • IE9+: Basic functionality (limited source map support)
  • Node.js: Full compatibility with CommonJS
  • Source Maps: Enhanced debugging in supporting environments
  • Cross-Origin: Handles cross-origin script limitations gracefully

Note: For Node.js-only applications, consider using the dedicated stack-trace package which provides similar API with optimizations specifically for server environments.