Skip to content

Add error message to report #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 28, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Generate, parse and enhance JavaScript stack traces in all browsers

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).

stacktrace.js uses browsers' `Error.stack` mechanism to generate stack traces, parses them, enhances them with
[source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) and uses
stacktrace.js uses browsers' `Error.stack` mechanism to generate stack traces, parses them, enhances them with
[source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) and uses
[Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
to return an Array of [StackFrames](https://github.com/stacktracejs/stackframe).

Expand All @@ -16,10 +16,10 @@ to return an Array of [StackFrames](https://github.com/stacktracejs/stackframe).
#### Get a stack trace from current location
```js
var callback = function(stackframes) {
var stringifiedStack = stackframes.map(function(sf) {
return sf.toString();
}).join('\n');
console.log(stringifiedStack);
var stringifiedStack = stackframes.map(function(sf) {
return sf.toString();
}).join('\n');
console.log(stringifiedStack);
};

var errback = function(err) { console.log(err.message); };
Expand All @@ -40,7 +40,7 @@ window.onerror = function(msg, file, line, col, error) {

#### Get stack trace from an Error
```js
var error = new Error('BOOM!');
var error = new Error('BOOM!');

StackTrace.fromError(error).then(callback).catch(errback)
=> Promise(Array[StackFrame], Error)
Expand Down Expand Up @@ -81,48 +81,49 @@ http://cdnjs.com/libraries/stacktrace.js
Generate a backtrace from invocation point, then parse and enhance it.

**(Optional) options: Object**
* *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
* *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
* *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
* *offline: Boolean (default: false)* - Set to `true` to prevent all network requests

#### `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)])
Given an Error object, use [error-stack-parser](https://github.com/stacktracejs/error-stack-parser)
to parse it and enhance location information with [stacktrace-gps](https://github.com/stacktracejs/stacktrace-gps).

**error: Error**

**(Optional) options: Object**
* *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
* *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
* *offline: Boolean (default: false)* - Set to `true` to prevent all network requests

#### `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)])
Use [stack-generator](https://github.com/stacktracejs/stack-generator) to generate a backtrace by walking the `arguments.callee.caller` chain.

**(Optional) options: Object**
* *filter: Function([StackFrame](https://github.com/stacktracejs/stackframe) => Boolean)* - Only include stack entries matching for which `filter` returns `true`
* *sourceCache: Object (String URL => String Source)* - Pre-populate source cache to avoid network requests
* *offline: Boolean (default: false)* - Set to `true` to prevent all network requests

#### `StackTrace.instrument(fn, callback, /*optional*/ errback)` => Function
* Given a function, wrap it such that invocations trigger a callback that is called with a stack trace.

* **fn: Function** - to wrap, call callback on invocation and call-through
* **callback: Function** - to call with stack trace (generated by `StackTrace.get()`) when fn is called
* **(Optional) errback: Function** - to call with Error object if there was a problem getting a stack trace.
* **(Optional) errback: Function** - to call with Error object if there was a problem getting a stack trace.
Fails silently (though `fn` is still called) if a stack trace couldn't be generated.

#### `StackTrace.deinstrument(fn)` => Function
Given a function that has been instrumented, revert the function to it's original (non-instrumented) state.

* **fn: Function** - Instrumented Function

#### `StackTrace.report(stackframes, url)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(String)
Given an Array of StackFrames, serialize and POST to given URL. Promise is resolved with response text from POST request.
#### `StackTrace.report(message, stackframes, url)` => [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)(String)
Given an an error message and Array of StackFrames, serialize and POST to given URL. Promise is resolved with response text from POST request.

Example JSON POST data:
```
{
message: 'BOOM',
stack: [
{functionName: 'fn', fileName: 'file.js', lineNumber: 32, columnNumber: 1},
{functionName: 'fn2', fileName: 'file.js', lineNumber: 543, columnNumber: 32},
Expand All @@ -131,6 +132,7 @@ Example JSON POST data:
}
```

* **message: String** - The error message
* **stackframes: Array([StackFrame](https://github.com/stacktracejs/stackframe))** - Previously wrapped Function
* **url: String** - URL to POST stack JSON to

Expand All @@ -140,8 +142,8 @@ Example JSON POST data:
> **HEADS UP**: You won't get the benefit of [source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/)
in IE9- or other very old browsers.

## Using node.js/io.js only?
I recommend the [stack-trace node package](https://www.npmjs.com/package/stack-trace) specifically built for node.
## Using node.js/io.js only?
I recommend the [stack-trace node package](https://www.npmjs.com/package/stack-trace) specifically built for node.
It has a very similar API and also supports source maps.

## Contributing
Expand Down
8 changes: 5 additions & 3 deletions spec/stacktrace-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,16 @@ describe('StackTrace', function() {

it('sends POST request to given URL', function(done) {
var url = 'http://domain.ext/endpoint';
var errorMsg = 'BOOM';
var stackframes = [new StackFrame('fn', undefined, 'file.js', 32, 1)];

StackTrace.report(stackframes, url).then(callback, done.fail)['catch'](done.fail);
StackTrace.report(errorMsg, stackframes, url).then(callback, done.fail)['catch'](done.fail);

var postRequest = jasmine.Ajax.requests.mostRecent();
postRequest.respondWith({status: 201, contentType: 'text/plain', responseText: 'OK'});

function callback() {
expect(postRequest.data()).toEqual({stack: stackframes});
expect(postRequest.data()).toEqual({message: errorMsg, stack: stackframes});
expect(postRequest.method).toBe('post');
expect(postRequest.url).toBe(url);
done();
Expand All @@ -211,10 +212,11 @@ describe('StackTrace', function() {

it('rejects if POST request fails', function(done) {
var url = 'http://domain.ext/endpoint';
var errorMsg = 'BOOM';
var stackframes = [new StackFrame('fn', undefined, 'file.js', 32, 1)];

jasmine.Ajax.stubRequest(url).andError();
StackTrace.report(stackframes, url).then(done.fail, done)['catch'](done);
StackTrace.report(errorMsg, stackframes, url).then(done.fail, done)['catch'](done);
});
});
});
6 changes: 3 additions & 3 deletions stacktrace.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@
},

/**
* Given an Array of StackFrames, serialize and POST to given URL.
* Given an error message and Array of StackFrames, serialize and POST to given URL.
*
* @param {Array} stackframes
* @param {String} url
*/
report: function StackTrace$$report(stackframes, url) {
report: function StackTrace$$report(errorMsg, stackframes, url) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting the error message first breaks the API, I'm afraid.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting to move it to last? Or is creating a completely separate method better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving the argument would be sufficient. We may also only want to assign the message if it's populated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.onerror = reject;
Expand All @@ -183,7 +183,7 @@
};
req.open('post', url);
req.setRequestHeader('Content-Type', 'application/json');
req.send(JSON.stringify({stack: stackframes}));
req.send(JSON.stringify({message: errorMsg, stack: stackframes}));
});
}
};
Expand Down