16

I've been doing some research into how we can catch JavaScript errors, and then send them off to our own system for internal logging (so we can try and replicate where possible, and fix any possible bugs). So far I have found quite a few paid services:

The TrackJS one does look interesting, but we really can't afford to be spending out yet more money each month. I then came across this libray:

http://www.stacktracejs.com/#!/docs/stacktrace-js

I can't seem to get it going though. Here is what I'm trying:

window.onerror = function(msg, file, line, col, error) {
    StackTrace.fromError(error).then(callback).catch(errback);
};

var callback = function(stackframes) {
    var stringifiedStack = stackframes.map(function(sf) {
        return sf.toString();
    }).join('\n');
    console.log(stringifiedStack);
};

var errback = function(err) {
        console.log(err);
};

StackTrace.get().then(callback).catch(errback);

... and all I get back is:

TypeError: ErrorStackParser is undefined

var stackframes = ErrorStackParser.parse(error);

Can anyone else suggest a solution, or see what I'm doing wrong with the stacktrace.js script?

UPDATE: With the help below, I was able to at least get it to do something now. Turns out you need multiple js libs:

However, I still can't seem to get it going.

var callback = function(stackframes) {
    console.log(stackframes)
    var stringifiedStack = stamap(function(sf) {
        return sf.toString();
    }).join('\n');
    console.log(stringifiedStack);
};

var errback = function(err) { console.log(err.message); };

 try {
    foo;
 } catch(e) {
    StackTrace.get().then(callback).catch(errback);
 }

While I now get errors logged in the console, the line numbers and error messages are less than useless :( Example:

.get()@https://cdn.steampunkjunkies.net/2014/js/scripts-all11.js:5:19706
{anonymous}()@https://cdn.steampunkjunkies.net/2014/js/scripts-all11.js:84:2

Line 84 is the caller function:

StackTrace.get().then(callback).catch(errback);

...and line 5, is the minified include of stacktrace.min.js (in my main JS file)

I'm a bit baffled as to how we can even get any useful information out of this :/

UPDATE 2: Ok, I'm getting closer!

var callback = function(stackframes) {
    var stringifiedStack = stackframes.map(function(sf) {
        return sf.toString();
    }).join('\n');
    alert(stringifiedStack);
};

var errback = function(err) { console.log(err.message); };

 try {
    var foo = 0;
    foo / 1;

    aklert;

    test;
 } catch(e) {
    StackTrace.fromError(e).then(callback).catch(errback);
 }

This now prints out an alert() message:

{anonymous}()@https://cdn.steampunkjunkies.net/2014/js/scripts-all11.js:73:1

However, thats not all the information I need. Obviously it needs a nice message (i.e var x cannot be undefined)

Anyone got any ideas?

I did try storing them in an array (with the line number and col number), but that doesn't work across all browsers (and ironically, the debug code caused a fatal :))

UPDATE 3

Ok, well we are getting closer :)

var callback = function(stackframes) {
    var stringifiedStack = stackframes.map(function(sf) {
        return sf.toString();
    }).join('\n');
    alert(stringifiedStack);
};

var errback = function(err) { console.log(err.message); };

window.onerror = function(msg, file, line, col, error) {
    var callback = reportWithMessage(msg);
    StackTrace.fromError(error).then(callback).catch(errback);
};


function reportWithMessage(message) {
    return function report(stack) {
        var yourErrorCollectorUrl = 'https://steampunkjunkiesdev.net/cgi-bin/debug.cgi';
        stack.message = message;
        StackTrace.report(stack, yourErrorCollectorUrl);
    };
}

 try {
    var foo = 0;
    foo / 1;

    aklert;

    test;
 } catch(e) {
    StackTrace.get().then(reportWithMessage()).catch(errback);
 }

enter image description here

Line 92 is this one}:

StackTrace.get().then(reportWithMessage()).catch(errback);

...so all its doing, is telling me that this function was called, but it no line number for the actual error.

Any ideas? I can't believe how complicated it is to catch JS errors and just report them back to a script. You would have thought with the last 20+ years of the Internet developing, something more compliant would have been developed for us developers :/

Eric Wendelin
  • 39,122
  • 8
  • 59
  • 87
Andrew Newby
  • 4,197
  • 2
  • 29
  • 59
  • 1
    `ErrorStackParser is undefined` makes me feel like it's not installed / imported on your file. Did you follow [the installation guide](http://www.stacktracejs.com/#!/docs/error-stack-parser) ? – pistou Nov 09 '15 at 15:50
  • @pistou thanks for the reply. I run `npm install stacktrace-js` to get the JS file - then I include the JS file (prior to my own code), and finally in my own code I have the code in the above. Maybe I'm missing a step? – Andrew Newby Nov 09 '15 at 15:58
  • I don't know StackTrace.JS but as far as I understand their website, it seems like `stacktrace-js` and `error-stack-parser` are two separated libraries (maybe one depending on the other) – pistou Nov 09 '15 at 16:01
  • @pistou - ah, well that would explain part of it! I'm used to all the modules for lib being in one download. I don't get any errors now, but I'm a bit baffled as to the error stack being outputted: `.get()@https://cdn.steampunkjunkies.net/2014/js/scripts-all11.js:8:19706 {anonymous}()@https://cdn.steampunkjunkies.net/2014/js/scripts-all11.js:25:1 `. Line 25 is the place where the debug is called: `StackTrace.get().then(callback).catch(errback); ` ... but it doesn't seem to give any other info (I've intentionally left a syntax error in the file, but nothing comes up) – Andrew Newby Nov 09 '15 at 16:19
  • @AndrewNewby you should post your solution that resolved this error, and then ask a new question for additional help – Adjit Nov 09 '15 at 17:28
  • @Adjit - that wasn't the solution to what I was asking (only part of it). I've updated my question above with more sample code. I'm getting there, but there is just the final bit of the error message that I just can't work out :( – Andrew Newby Nov 09 '15 at 18:18
  • Hi Andrew, I'm the creator of stacktrace.js. You're welcome to email me for help at me@eriwen.com anytime, but of course asking on SO is effective (I hope :) – Eric Wendelin Nov 09 '15 at 19:13

1 Answers1

4

I'm sorry for your troubles getting started. Please use dist/stacktrace.min.js which has all dependencies bundled. I filed this issue so we can make this clearer and others avoid the pain you've encountered: https://github.com/stacktracejs/stacktrace.js/issues/140

Regarding the Error message, it seems like you can do something with the msg parameter of window.onerror in your error reporting system. I understand that it's not straight-forward given there is no obvious place to store messages.

How about this?

window.onerror = function(msg, file, line, col, error) {
    var callback = reportWithMessage(msg);
    StackTrace.fromError(error).then(callback).catch(errback);
};


function reportWithMessage(message) {
    return function report(stack) {
        var yourErrorCollectorUrl = 'https://yourdomain.com/ec';
        stack.message = message;
        // HTTP POST with {message: String, stack: JSON}
        StackTrace.report(stack, yourErrorCollectorUrl);
    };
}

Outside of window.onerror you can maybe do:

StackTrace.get().then(reportWithMessage()).catch(errorhandler);

UPDATE: In the case where you've caught an Error, you want to use

StackTrace.fromError(error).then(...).catch(...);
Eric Wendelin
  • 39,122
  • 8
  • 59
  • 87
  • 1
    Thanks for the reply and sample code - that should do just what I need :) No need to apologize about it being confusing - I just appreciate the time you have spent on the project (I know as a coder, how time consuming stuff like this can be!) – Andrew Newby Nov 09 '15 at 19:45
  • not sure if this is a bug or not, but I can't seem to get the value passed in with `var yourErrorCollectorUrl = 'https://steampunkjunkies.net/cgi-bin/debug.cgi';`. I see the request, but **QUERY_STRING** is empty (for both `post` and `get`). Am I missing something? – Andrew Newby Nov 10 '15 at 09:15
  • Mmm actually, maybe its not working for me :( I'll update my post above with the code I'm using, and what its outputting – Andrew Newby Nov 10 '15 at 09:20
  • @AndrewNewby See my updated answer. I'm going to assume that __QUERY_STRING__ is something specific to CGI for getting the query string of a request. If that is the case, note that StackTrace.report() does an HTTP POST so you're looking for the stacktrace in the POST body. – Eric Wendelin Nov 10 '15 at 15:02
  • ah ok, makes sense. `$ENV{QUERY_STRING}` is the POST/GET request passed into a script. Its weird, as it looks like its passing something along - but then Firebug shows nothing up. I think I'm going to take a break from this, and come back to it with a fresh mind. Its doing my head in :) – Andrew Newby Nov 10 '15 at 15:14