1 | # stacktrace.js
|
---|
2 | Generate, parse and enhance JavaScript stack traces in all browsers
|
---|
3 |
|
---|
4 | [![Build Status](https://img.shields.io/travis/stacktracejs/stacktrace.js/master.svg?style=flat-square)](https://travis-ci.org/stacktracejs/stacktrace.js)
|
---|
5 | [![Coverage Status](https://img.shields.io/coveralls/stacktracejs/stacktrace.js.svg?style=flat-square)](https://coveralls.io/r/stacktracejs/stacktrace.js?branch=master)
|
---|
6 | [![GitHub license](https://img.shields.io/github/license/stacktracejs/stacktrace.js.svg?style=flat-square)](https://opensource.org/licenses/MIT)
|
---|
7 | [![CDNJS](https://img.shields.io/cdnjs/v/stacktrace.js.svg?style=flat-square)](https://cdnjs.com/libraries/stacktrace.js)
|
---|
8 | [![size with dependencies](https://img.shields.io/badge/size-29.9k-green.svg?style=flat-square)](https://github.com/stacktracejs/stacktrace.js/releases)
|
---|
9 | [![gzip size](https://img.shields.io/badge/gzipped-9.1k-green.svg?style=flat-square)](https://github.com/stacktracejs/stacktrace.js/releases)
|
---|
10 | [![module format](https://img.shields.io/badge/module%20format-umd-lightgrey.svg?style=flat-square&colorB=ff69b4)](https://github.com/stacktracejs/stacktrace.js/releases)
|
---|
11 |
|
---|
12 | Debug and profile your JavaScript with a [stack trace](http://en.wikipedia.org/wiki/Stack_trace) of function calls leading to an error (or any condition you specify).
|
---|
13 |
|
---|
14 | stacktrace.js uses browsers' `Error.stack` mechanism to generate stack traces, parses them, enhances them with
|
---|
15 | [source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) and uses
|
---|
16 | [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
|
---|
17 | to return an Array of [StackFrames](https://github.com/stacktracejs/stackframe).
|
---|
18 |
|
---|
19 | #### Upgrading? Check the [0.x -> 1.x Migration Guide](https://www.stacktracejs.com/#!/docs/v0-migration-guide)
|
---|
20 |
|
---|
21 | ## Usage
|
---|
22 | #### Get a stack trace from current location
|
---|
23 | ```js
|
---|
24 | var callback = function(stackframes) {
|
---|
25 | var stringifiedStack = stackframes.map(function(sf) {
|
---|
26 | return sf.toString();
|
---|
27 | }).join('\n');
|
---|
28 | console.log(stringifiedStack);
|
---|
29 | };
|
---|
30 |
|
---|
31 | var errback = function(err) { console.log(err.message); };
|
---|
32 |
|
---|
33 | StackTrace.get().then(callback).catch(errback);
|
---|
34 | //===> Promise(Array[StackFrame], Error)
|
---|
35 | //===> callback([
|
---|
36 | // StackFrame({functionName: 'func1', args: [], fileName: 'file.js', lineNumber: 203, columnNumber: 9}),
|
---|
37 | // StackFrame({functionName: 'func2', args: [], fileName: 'http://localhost:3000/file.min.js', lineNumber: 1, columnNumber: 3284})
|
---|
38 | //])
|
---|
39 | ```
|
---|
40 |
|
---|
41 | #### You can also get a stack trace synchronously
|
---|
42 | **HEADS UP:** This method does not resolve source maps or guess anonymous function names.
|
---|
43 |
|
---|
44 | ```js
|
---|
45 | StackTrace.getSync();
|
---|
46 | //==> [
|
---|
47 | // StackFrame({functionName: 'func1', args: [], fileName: 'file.js', lineNumber: 203, columnNumber: 9}),
|
---|
48 | // StackFrame({functionName: 'func2', args: [], fileName: 'http://localhost:3000/file.min.js', lineNumber: 1, columnNumber: 3284})
|
---|
49 | //]
|
---|
50 | ```
|
---|
51 |
|
---|
52 | #### window.onerror integration
|
---|
53 | Automatically handle errors
|
---|
54 | ```js
|
---|
55 | window.onerror = function(msg, file, line, col, error) {
|
---|
56 | // callback is called with an Array[StackFrame]
|
---|
57 | StackTrace.fromError(error).then(callback).catch(errback);
|
---|
58 | };
|
---|
59 | ```
|
---|
60 |
|
---|
61 | #### Get stack trace from an Error
|
---|
62 | ```js
|
---|
63 | var error = new Error('BOOM!');
|
---|
64 |
|
---|
65 | StackTrace.fromError(error).then(callback).catch(errback);
|
---|
66 | //===> Promise(Array[StackFrame], Error)
|
---|
67 | ```
|
---|
68 |
|
---|
69 | #### Generate a stacktrace from walking arguments.callee
|
---|
70 | This might capture arguments information, but isn't supported in ES5 strict-mode
|
---|
71 | ```js
|
---|
72 | StackTrace.generateArtificially().then(callback).catch(errback);
|
---|
73 | //===> Promise(Array[StackFrame], Error)
|
---|
74 | ```
|
---|
75 |
|
---|
76 | #### Trace every time a given function is invoked
|
---|
77 | ```js
|
---|
78 | // callback is called with an Array[StackFrame] every time wrapped function is called
|
---|
79 | var myFunc = function(arg) { return 'Hello ' + arg; };
|
---|
80 | var myWrappedFunc = StackTrace.instrument(myFunc, callback, errback);
|
---|
81 | //===> Instrumented Function
|
---|
82 | myWrappedFunc('world');
|
---|
83 | //===> 'Hello world'
|
---|
84 |
|
---|
85 | // Use this if you overwrote you original function
|
---|
86 | myFunc = StackTrace.deinstrument(myFunc);
|
---|
87 | //===> De-instrumented Function
|
---|
88 | ```
|
---|
89 |
|
---|
90 | ## Get stacktrace.js
|
---|
91 | ```
|
---|
92 | npm install stacktrace-js
|
---|
93 | bower install stacktrace-js
|
---|
94 | component install stacktracejs/stacktrace.js
|
---|
95 | http://cdnjs.com/libraries/stacktrace.js
|
---|
96 | ```
|
---|
97 |
|
---|
98 | ## API
|
---|
99 |
|
---|
100 | #### `StackTrace.get(/*optional*/ options)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(Array[[StackFrame](https://github.com/stacktracejs/stackframe)])
|
---|
101 | Generate a backtrace from invocation point, then parse and enhance it.
|
---|
102 |
|
---|
103 | **(Optional) options: Object**
|
---|
104 | * *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
|
---|
105 | * *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
|
---|
106 | * *offline: Boolean (default: false)* - Set to `true` to prevent all network requests
|
---|
107 |
|
---|
108 | #### `StackTrace.getSync(/*optional*/ options)` => Array[[StackFrame](https://github.com/stacktracejs/stackframe)]
|
---|
109 | Generate a backtrace from invocation point, then parse it. This method does not use source maps or guess anonymous functions.
|
---|
110 |
|
---|
111 | **(Optional) options: Object**
|
---|
112 | * *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
|
---|
113 |
|
---|
114 | #### `StackTrace.fromError(error, /*optional*/ options)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(Array[[StackFrame](https://github.com/stacktracejs/stackframe)])
|
---|
115 | Given an Error object, use [error-stack-parser](https://github.com/stacktracejs/error-stack-parser)
|
---|
116 | to parse it and enhance location information with [stacktrace-gps](https://github.com/stacktracejs/stacktrace-gps).
|
---|
117 |
|
---|
118 | **error: Error**
|
---|
119 |
|
---|
120 | **(Optional) options: Object**
|
---|
121 | * *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
|
---|
122 | * *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
|
---|
123 | * *offline: Boolean (default: false)* - Set to `true` to prevent all network requests
|
---|
124 |
|
---|
125 | #### `StackTrace.generateArtificially(/*optional*/ options)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(Array[[StackFrame](https://github.com/stacktracejs/stackframe)])
|
---|
126 | Use [stack-generator](https://github.com/stacktracejs/stack-generator) to generate a backtrace by walking the `arguments.callee.caller` chain.
|
---|
127 |
|
---|
128 | **(Optional) options: Object**
|
---|
129 | * *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
|
---|
130 | * *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
|
---|
131 | * *offline: Boolean (default: false)* - Set to `true` to prevent all network requests
|
---|
132 |
|
---|
133 | #### `StackTrace.instrument(fn, callback, /*optional*/ errback)` => Function
|
---|
134 | * Given a function, wrap it such that invocations trigger a callback that is called with a stack trace.
|
---|
135 |
|
---|
136 | * **fn: Function** - to wrap, call callback on invocation and call-through
|
---|
137 | * **callback: Function** - to call with stack trace (generated by `StackTrace.get()`) when fn is called
|
---|
138 | * **(Optional) errback: Function** - to call with Error object if there was a problem getting a stack trace.
|
---|
139 | Fails silently (though `fn` is still called) if a stack trace couldn't be generated.
|
---|
140 |
|
---|
141 | #### `StackTrace.deinstrument(fn)` => Function
|
---|
142 | Given a function that has been instrumented, revert the function to it's original (non-instrumented) state.
|
---|
143 |
|
---|
144 | * **fn: Function** - Instrumented Function
|
---|
145 |
|
---|
146 | #### `StackTrace.report(stackframes, url, message, requestOptions)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(String)
|
---|
147 | Given an an error message and Array of StackFrames, serialize and POST to given URL. Promise is resolved with response text from POST request.
|
---|
148 |
|
---|
149 | Example JSON POST data:
|
---|
150 | ```
|
---|
151 | {
|
---|
152 | message: 'BOOM',
|
---|
153 | stack: [
|
---|
154 | {functionName: 'fn', fileName: 'file.js', lineNumber: 32, columnNumber: 1},
|
---|
155 | {functionName: 'fn2', fileName: 'file.js', lineNumber: 543, columnNumber: 32},
|
---|
156 | {functionName: 'fn3', fileName: 'file.js', lineNumber: 8, columnNumber: 1}
|
---|
157 | ]
|
---|
158 | }
|
---|
159 | ```
|
---|
160 |
|
---|
161 | * **stackframes: Array([StackFrame](https://github.com/stacktracejs/stackframe))** - Previously wrapped Function
|
---|
162 | * **url: String** - URL to POST stack JSON to
|
---|
163 | * **message: String** - The error message
|
---|
164 | * **requestOptions: Object** - HTTP request options object. Only `headers: {key: val}` is supported.
|
---|
165 |
|
---|
166 | ## Browser Support
|
---|
167 | [![Sauce Test Status](https://saucelabs.com/browser-matrix/stacktracejs.svg)](https://saucelabs.com/u/stacktracejs)
|
---|
168 |
|
---|
169 | > **HEADS UP**: You won't get the benefit of [source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/)
|
---|
170 | in IE9- or other very old browsers.
|
---|
171 |
|
---|
172 | ## Using node.js/io.js only?
|
---|
173 | I recommend the [stack-trace node package](https://www.npmjs.com/package/stack-trace) specifically built for node.
|
---|
174 | It has a very similar API and also supports source maps.
|
---|
175 |
|
---|
176 | ## Contributing
|
---|
177 | This project adheres to the [Open Code of Conduct](http://todogroup.org/opencodeofconduct/#stacktrace.js/me@eriwen.com). By participating, you are expected to honor this code.
|
---|
178 |
|
---|
179 | Want to be listed as a *Contributor*? Start with the [Contributing Guide](https://github.com/stacktracejs/stacktrace.js/blob/master/.github/CONTRIBUTING.md)!
|
---|
180 |
|
---|
181 | This project is made possible due to the efforts of these fine people:
|
---|
182 |
|
---|
183 | * [Eric Wendelin](https://www.eriwen.com)
|
---|
184 | * [Victor Homyakov](https://github.com/victor-homyakov)
|
---|
185 | * [Oliver Salzburg](https://github.com/oliversalzburg)
|
---|
186 | * [Many others](https://github.com/stacktracejs/stacktrace.js/graphs/contributors)
|
---|