0
# StackTrace.js
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: stacktrace-js
7
- **Package Type**: npm
8
- **Language**: JavaScript (with TypeScript definitions)
9
- **Installation**:
10
- npm: `npm install stacktrace-js`
11
- bower: `bower install stacktrace-js`
12
- CDN: `https://cdnjs.com/libraries/stacktrace.js`
13
14
## Core Imports
15
16
```javascript
17
import StackTrace from "stacktrace-js";
18
```
19
20
For CommonJS:
21
22
```javascript
23
const StackTrace = require("stacktrace-js");
24
```
25
26
Browser (global):
27
28
```javascript
29
// Available as window.StackTrace after including the script
30
```
31
32
UMD (AMD):
33
34
```javascript
35
define(['stacktrace'], function(StackTrace) {
36
// Use StackTrace here
37
});
38
```
39
40
## Basic Usage
41
42
```javascript
43
import StackTrace from "stacktrace-js";
44
45
// Get current stack trace
46
StackTrace.get()
47
.then(stackframes => {
48
stackframes.forEach(frame => {
49
console.log(frame.toString());
50
});
51
})
52
.catch(err => console.error(err));
53
54
// Parse an error object
55
try {
56
throw new Error("Something went wrong!");
57
} catch (error) {
58
StackTrace.fromError(error)
59
.then(stackframes => {
60
console.log("Stack trace:", stackframes);
61
});
62
}
63
```
64
65
## Architecture
66
67
StackTrace.js is built around several key components:
68
69
- **Stack Generation**: Multiple strategies for capturing stack traces (Error.stack, artificial generation)
70
- **Stack Parsing**: Integration with error-stack-parser for cross-browser stack trace parsing
71
- **Source Enhancement**: Uses stacktrace-gps for source map resolution and function name guessing
72
- **Promise-based API**: Asynchronous operations return Promises for enhanced stack frames
73
- **Synchronous Fallback**: getSync() method for immediate results without source map enhancement
74
- **Function Instrumentation**: Capability to wrap functions for automatic stack trace capture
75
- **Network Reporting**: Built-in error reporting to remote endpoints
76
77
## Capabilities
78
79
### Stack Trace Generation
80
81
Core functionality for capturing stack traces from various sources with optional source map enhancement.
82
83
```javascript { .api }
84
/**
85
* Get a backtrace from invocation point with source map enhancement
86
* @param options - Optional configuration object
87
* @returns Promise resolving to Array of StackFrame objects
88
*/
89
function get(options?: StackTraceOptions): Promise<StackFrame[]>;
90
91
/**
92
* Get a backtrace synchronously (no source maps or function name guessing)
93
* @param options - Optional configuration object
94
* @returns Array of StackFrame objects
95
*/
96
function getSync(options?: StackTraceOptions): StackFrame[];
97
```
98
99
**Usage Examples:**
100
101
```javascript
102
// Asynchronous with source map enhancement
103
StackTrace.get({
104
filter: frame => !frame.functionName?.includes('internal'),
105
offline: false
106
}).then(stackframes => {
107
console.log('Enhanced stack trace:', stackframes);
108
});
109
110
// Synchronous (faster, less detailed)
111
const frames = StackTrace.getSync({
112
filter: frame => frame.fileName?.includes('my-app')
113
});
114
console.log('Sync stack trace:', frames);
115
```
116
117
### Error Stack Parsing
118
119
Parse existing Error objects and enhance them with source maps and location information.
120
121
```javascript { .api }
122
/**
123
* Parse Error object and enhance with source maps
124
* @param error - Error object to parse
125
* @param options - Optional configuration object
126
* @returns Promise resolving to Array of StackFrame objects
127
*/
128
function fromError(error: Error, options?: StackTraceOptions): Promise<StackFrame[]>;
129
```
130
131
**Usage Examples:**
132
133
```javascript
134
// Parse caught errors
135
window.onerror = function(msg, file, line, col, error) {
136
StackTrace.fromError(error, {
137
sourceCache: {
138
'http://example.com/script.js': cachedSource
139
}
140
}).then(stackframes => {
141
// Send to error reporting service
142
reportError(msg, stackframes);
143
});
144
};
145
146
// Parse custom errors
147
const customError = new Error("Custom error");
148
StackTrace.fromError(customError).then(frames => {
149
console.log("Parsed error stack:", frames);
150
});
151
```
152
153
### Artificial Stack Generation
154
155
Generate stack traces by walking the call chain when Error.stack is not available.
156
157
```javascript { .api }
158
/**
159
* Generate backtrace by walking arguments.callee.caller chain
160
* @param options - Optional configuration object
161
* @returns Promise resolving to Array of StackFrame objects
162
*/
163
function generateArtificially(options?: StackTraceOptions): Promise<StackFrame[]>;
164
```
165
166
**Usage Examples:**
167
168
```javascript
169
// Fallback for environments without Error.stack
170
StackTrace.generateArtificially({
171
filter: frame => frame.functionName !== 'anonymous'
172
}).then(stackframes => {
173
console.log("Artificial stack trace:", stackframes);
174
});
175
```
176
177
### Function Instrumentation
178
179
Wrap functions to automatically capture stack traces on invocation for debugging and profiling.
180
181
```javascript { .api }
182
/**
183
* Wrap function to trigger callback with stack trace on each invocation
184
* @param fn - Function to instrument
185
* @param callback - Function called with stack trace array
186
* @param errback - Optional error callback function
187
* @param thisArg - Optional context object
188
* @returns Instrumented function
189
* @throws Error if fn is not a function
190
*/
191
function instrument<TFunc extends Function>(
192
fn: TFunc,
193
callback: (stackFrames: StackFrame[]) => void,
194
errback?: (error: Error) => void,
195
thisArg?: any
196
): TFunc;
197
198
/**
199
* Revert instrumented function to original state
200
* @param fn - Instrumented function to revert
201
* @returns Original (non-instrumented) function
202
* @throws Error if fn is not a function
203
*/
204
function deinstrument<TFunc extends Function>(fn: TFunc): TFunc;
205
```
206
207
**Usage Examples:**
208
209
```javascript
210
// Instrument a function for debugging
211
function processData(data) {
212
return data.map(item => item * 2);
213
}
214
215
const instrumentedProcess = StackTrace.instrument(
216
processData,
217
stackframes => {
218
console.log("processData called from:", stackframes[0]);
219
},
220
error => console.error("Failed to get stack trace:", error)
221
);
222
223
// Use the instrumented function
224
const result = instrumentedProcess([1, 2, 3]);
225
226
// Restore original function
227
const originalProcess = StackTrace.deinstrument(instrumentedProcess);
228
```
229
230
### Error Reporting
231
232
Submit stack trace data to remote endpoints for centralized error tracking.
233
234
```javascript { .api }
235
/**
236
* Serialize stackframes and POST to given URL
237
* @param stackframes - Array of StackFrame objects
238
* @param url - Target URL for POST request
239
* @param errorMsg - Optional error message string
240
* @param requestOptions - Optional HTTP request options (headers supported)
241
* @returns Promise resolving to response text
242
*/
243
function report(
244
stackframes: StackFrame[],
245
url: string,
246
errorMsg?: string,
247
requestOptions?: object
248
): Promise<any>;
249
```
250
251
**Usage Examples:**
252
253
```javascript
254
// Report errors to monitoring service
255
StackTrace.get().then(stackframes => {
256
return StackTrace.report(
257
stackframes,
258
'https://api.errorservice.com/errors',
259
'Unhandled exception occurred',
260
{
261
headers: {
262
'Authorization': 'Bearer token123',
263
'Content-Type': 'application/json'
264
}
265
}
266
);
267
}).then(response => {
268
console.log("Error reported successfully:", response);
269
});
270
```
271
272
## Types
273
274
```javascript { .api }
275
interface StackTraceOptions {
276
/** Filter function for stack frames */
277
filter?: (stackFrame: StackFrame) => boolean;
278
/** Pre-populated source cache to avoid network requests */
279
sourceCache?: SourceCache;
280
/** Set to true to prevent all network requests */
281
offline?: boolean;
282
}
283
284
interface SourceCache {
285
[url: string]: string | Promise<string>;
286
}
287
288
interface StackFrame {
289
/** Whether frame is constructor call */
290
isConstructor?: boolean;
291
/** Whether frame is from eval */
292
isEval?: boolean;
293
/** Whether frame is native code */
294
isNative?: boolean;
295
/** Whether frame is top-level */
296
isTopLevel?: boolean;
297
/** Column number in source */
298
columnNumber?: number;
299
/** Line number in source */
300
lineNumber?: number;
301
/** Source file name/URL */
302
fileName?: string;
303
/** Function name */
304
functionName?: string;
305
/** Source code line */
306
source?: string;
307
/** Function arguments */
308
args?: any[];
309
/** Origin frame for eval */
310
evalOrigin?: StackFrame;
311
312
/** Get/set methods for all properties */
313
getIsConstructor(): boolean;
314
setIsConstructor(): void;
315
getIsEval(): boolean;
316
setIsEval(): void;
317
getIsNative(): boolean;
318
setIsNative(): void;
319
getIsTopLevel(): boolean;
320
setIsTopLevel(): void;
321
getColumnNumber(): number;
322
setColumnNumber(): void;
323
getLineNumber(): number;
324
setLineNumber(): void;
325
getFileName(): string;
326
setFileName(): void;
327
getFunctionName(): string;
328
setFunctionName(): void;
329
getSource(): string;
330
setSource(): void;
331
getArgs(): any[];
332
setArgs(): void;
333
getEvalOrigin(): StackFrame;
334
setEvalOrigin(): void;
335
336
/** String representation */
337
toString(): string;
338
}
339
```
340
341
## Error Handling
342
343
StackTrace.js includes built-in error handling patterns:
344
345
- **Promise Rejection**: All async methods return Promises that reject on errors
346
- **Fallback Strategies**: Automatically falls back to artificial generation when Error.stack unavailable
347
- **Silent Failures**: Instrumentation fails silently while still calling the original function
348
- **Network Errors**: Report function handles HTTP error responses and network failures
349
350
Common error scenarios:
351
352
```javascript
353
// Automatic error handling with window.onerror
354
window.onerror = function(msg, file, line, col, error) {
355
StackTrace.fromError(error).then(stackframes => {
356
console.log('Error stack trace:', stackframes);
357
// Send to error reporting service
358
}).catch(err => {
359
console.log('Failed to parse error:', err.message);
360
});
361
};
362
363
// Handle parsing failures
364
StackTrace.fromError(malformedError)
365
.catch(err => {
366
console.log("Failed to parse error:", err.message);
367
// Fallback to artificial generation
368
return StackTrace.generateArtificially();
369
});
370
371
// Handle network failures in reporting
372
StackTrace.report(frames, 'https://unreachable.com/api')
373
.catch(err => {
374
console.log("Failed to report error:", err.message);
375
// Could fallback to local storage or console logging
376
});
377
```
378
379
## Browser Compatibility
380
381
- **Modern Browsers**: Full functionality including source maps
382
- **IE9+**: Basic functionality (limited source map support)
383
- **Node.js**: Full compatibility with CommonJS
384
- **Source Maps**: Enhanced debugging in supporting environments
385
- **Cross-Origin**: Handles cross-origin script limitations gracefully
386
387
> **Note**: For Node.js-only applications, consider using the dedicated [stack-trace](https://www.npmjs.com/package/stack-trace) package which provides similar API with optimizations specifically for server environments.