stacktracejs / stacktrace.js Goto Github PK
View Code? Open in Web Editor NEWGenerate, parse, and enhance JavaScript stack traces in all web browsers
Home Page: https://www.stacktracejs.com/
License: MIT License
Generate, parse, and enhance JavaScript stack traces in all web browsers
Home Page: https://www.stacktracejs.com/
License: MIT License
See "findFunctionName" unit test. Brief synopsis:
var a = function() {}, b = function() {};
Will always only capture a().
Html and JavaScript source code at http://jsbin.com/iyifuh/9 I am not 100% sure how to make JSBIN work, but you can view source to capture the source codes. My browser is IE8.
This is what it captured, but did not tell me function name.
error: at document path 'http://localhost:2692/'.
at function
at function
at function
at function
<script type="text/javascript" src="path/to/stacktrace.js" />
doesn't seem to work in chrome. Change it to:
<script src="path/to/stacktrace.js"></script>
Issue 1:
Run this:
<html><head><script src="stacktrace.js"></script>
<script>
function foo() {
bar(2);
}
function bar(n) {
if (n < 2)
abc();
bar(n-1);
}
var lastError;
try {
// error producing code
foo();
} catch(e) {
lastError = e;
// do something else with error
}
// Returns stacktrace from lastError!
alert (printStackTrace({e: lastError}).join('\n'));
</script>
</head>
<body></body>
</html>
Result:
In IE:
{anonymous}([object Error])
printStackTrace(#object)
In FF:
bar(1)@file:///D:/test/javascriptStackTrace/testcase1.html:12
bar(2)@file:///D:/test/javascriptStackTrace/testcase1.html:13
foo()@file:///D:/test/javascriptStackTrace/testcase1.html:8
@file:///D:/test/javascriptStackTrace/testcase1.html:18
What print in FF is expected while the information in IE is a little simple, but I'm not sure whether I'm using it correctly?
Issue 2:
Run this:
<html><head><script src="stacktrace.js"></script>
<script>
window.onerror = function(msg, file, line) {
alert(printStackTrace().join('\n'));
return true;
}
function foo() {
bar(2);
}
function bar(n) {
if (n < 2)
abc();
bar(n-1);
}
foo();
</script>
</head>
<body></body>
</html>
Result:
In IE (The same as the first case):
{anonymous}([object Error])
printStackTrace(#object)
In FF (The stack trace is different from the first case):
{anonymous}()@file:///D:/test/javascriptStackTrace/stacktrace.js:74
{anonymous}(null)@file:///D:/test/javascriptStackTrace/stacktrace.js:72
printStackTrace()@file:///D:/test/javascriptStackTrace/stacktrace.js:58
{anonymous}("abc is not defined","file:///D:/test/javascriptStackTrace/testcase1.html",17)@file:///D:/test/javascriptStackTrace/testcase1.html:8
In short:
I have two issues, one is the stack trace from IE is different and less information than FF.
Another one is the stack trace become not so helpful if I print stack in window.onerror.
Maybe I have some incorrect method in using your library, or they are already known issue?
Hope for help.
Thanks
Seems useful enough. How hard could it be?
The stringifyArguments function mutates arrays in-place, which means it may end up mutating every argument list on the stack when you call printStackTrace. Because it recurses, any arrays or objects passed as arguments will also get mutated. Every call, for example, adds a pair of quotes around every string in the argument list.
Naturally, this breaks EVERYTHING.
Here's a fixed version of stringifyArguments:
stringifyArguments: function(args) {
var result = [];
var slice = Array.prototype.slice;
for (var i = 0; i < args.length; ++i) {
var arg = args[i];
if (arg === undefined) {
result[i] = 'undefined';
} else if (arg === null) {
result[i] = 'null';
} else if (arg.constructor) {
if (arg.constructor === Array) {
if (arg.length < 3) {
result[i] = '[' + this.stringifyArguments(arg) + ']';
} else {
result[i] = '[' + this.stringifyArguments(slice.call(arg, 0, 1)) + '...' + this.stringifyArguments(slice.call(arg, -1)) + ']';
}
} else if (arg.constructor === Object) {
result[i] = '#object';
} else if (arg.constructor === Function) {
result[i] = '#function';
} else if (arg.constructor === String) {
result[i] = '"' + arg + '"';
}
}
}
return result.join(',');
},
http://www.stacktracejs.org/ is down, will it come back at some time?
Otherwise the readme should get updated.
I get not well-formed messages in the javascript log when working with a html+js page on the file system.
It might be related to firefox attempting to parse the ajax response as JSON.
I tried to find a workaround, but except turning the function name feature off (which is working), I didn't find a solution.
There are multiple issues that JSLint catches with javascript-stacktrace. I am working those through but there are some that I have been unable to solve.
For example, the "(0)();" rows come out with "Bad invocation." -error.
And, "var reStack = /{anonymous}(.*)@(\w+://([-\w.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/;" -row has three separate errors: Unescaped '{', Unescaped '}' and Unescaped '-'.
Right now the different browsers return the individual entries in a different format, e.g. chrome it looks like
0: "Object.run (http://localhost:8080/resources/app.core.resources/stacktrace.js:75:14)"
1: "printStackTrace (http://localhost:8080/resources/app.core.resources/stacktrace.js:59:20)"
2: "Object.log (http://localhost:8080/resources/app.log.resources/log.js:96:13)"
3: "http://localhost:8080/resources/app.log.resources/log.js:128:7"
While the same code in firefox looks like
0 "{anonymous}()@http://localhost:8080/resources/app.log.resources/stacktrace.js:70"
1 "{anonymous}(null)@http://localhost:8080/resources/app.log.resources/stacktrace.js:68"
2 "printStackTrace()@http://localhost:8080/resources/app.log.resources/stacktrace.js:59"
3 "{anonymous}("Logging started")@http://localhost:8080/resources/app.log.resources/log.js:96"
4 "@http://localhost:8080/resources/app.log.resources/log.js:128"
Opera and other browser look yet different.
It might be useful if stacktrace.js entries would be full objects with members "function", "url", "line", "column". So one line of the above output would look like
entry = { function : 'printStackTrace', url : 'http://localhost:8080/resources/app.log.resources/log.js', line : 96, column: 12 }
The NPM package seems to be out of date (at 0.5.0). Mind updating it?
In IE, the stack is preserved when calling printStackTrace() from window.onerror. However, Firefox does not "call" window.onerror from a failing function, therefore part of the stack is lost.
One solution may be to figure out the top of the stack from the file and line number passed in to window.onerror. This would be implemented as some sort of option that tells stacktrace.js where to look, and it would figure out what function the error came from (hopefully).
If I'm just doing something wrong then my apologies up front. I didn't see a forum so I'm posting this here. I'm getting the following Exception when printStackTrace() is called:
TypeError: Object # has no method 'undef'
This happens in Chrome. In IE I see createException in the stack trace but not the above error message. What can I do about this?
First, thanks for the great project!
I found a slight issue in findFunctionName: the regex doesn't recognize the '$' character in function names, which is valid (along with underscore) per 7.6 Identifier Names and Identifiers
of the ECMA-262 specification. Also, numbers are not allowed as the first character of identifiers.
On my local copy, I changed the following part of each regular expression:
/['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*
to:
/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*
In two of three examples of printStackTrace usage in readme file incorrect case "printStacktrace" is used. I've copy-pasted one of examples from readme directly into my page to find one error and lost about a half of hour to find and fix another error - why printStackTrace would not work (because of mistyped printStacktrace).
Hey Guys
I stumbled upon this as I was trying to solve my issue:
I must capture all errors using try...catch block. On safari, the object that is passed to catch as a "line" properly that gives me the line of where the original error occurred. on I Phone, all I get is "message" property - no line number of the original error.
Is there a solution for this problem? I see this utility also does not get the stack trace for safari, but all i need, is a line number. Wonder if you guys have the same issue. I found remarkably little info on this problem...
I've got a very basic exception class in .js that makes use of the stacktrace.js tool (which is AWESOME).
MyError = function MyError__construct( settings_obj ) {
if ( !( this instanceof MyError ) ) {
return;
}
this.message = "Unknown exception";
this.not_critical = false;
this.stack_trace = printStackTrace();
if ( typeof settings_obj === "object" ) {
this.message = settings_obj.message
this.not_critical = settings_obj.not_critical
}
}
However, I was doing some testing today ensuring my project can handle html-escaping properly and I noticed that if message
contains escaped quotes, I got an exception. For instance, if message
is "<script>alert(\"Security fail!\");</script>"
I get the following exception thrown in FF 23 (caught by Firebug):
SyntaxError: illegal character
alert(\"Security fail\");
The exception is marked as stacktrace.js (line 56, col 6)
Any thoughts would be greatly appreciated.
Im using printStackTrace (HEAD) on RequireJS 2.1.6 and am getting printStackTrace is not defined
upon calling printStackTrace()
.
requirejs.config({
paths : {
'stacktrace' : 'path/to/stacktrace',
}
});
I followed the trace and line 14 of stacktrace.js is called but does not seem to do its job for some reason.
Any help is greatly appreciated. =)
The printStackTrace()
method doesn't do what it says it does. To print a stack trace means to display it to the user. A method that merely returns a value is called a getter
, not a printer
. In other words, printStackTrace()
acts the way a function called getStackTrace()
should act. A function's name shouldn't contradict what the function does. Anyone reading the words printStackTrace()
should legitimately conclude that a stack trace is being printed. Obscure identifiers are awful enough, but a policy of naming methods in a way that contradicts what the methods actually do is devastating to a programmer's understanding of code. I prefer to keep such poisons out of my projects on general principle. Though this one specific issue is minor enough to ignore this time, that doesn't make misnaming methods an acceptable policy. This is not subjective or arbitrary, there is a real, objective difference between the concepts print
and get
.
In Opera 11.51 (Linux) there is no file names in stack trace. Stacktrace looks like:
{anonymous}(text)@:77:4
{anonymous}()@:300:0
{anonymous}()@:71:4
{anonymous}(c)@:17:2568
In other browsers stacktrace of the same error contains correct file names.
If OOP approach is used all functions are anonymous (in Safari, Opera 9+, IE, and others). In this case generated stack trace is absolutely useless:
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
It is not so hard to take function source (arguments.callee.toSource()) and find it in the source file. From that, line number can be calculated and real function name can be detected. This would add a little overheat but I think it's worth it.
Not really sure what this is doing, but the error above is generated by line 70 of printStackTrace.implementation.prototype.run().
var _err = undef << 1;
Kills IE8 dead.
Hi,
I am trying to use this library to capture the origin of a change to window.location and have had some success for FF and IE, but chrome doesn't seem to preserve the source of the originating window.location change.
Any ideas on how to achieve this, or another work around to get the same result?
Cheers,
Julian.
The docs say the error message is not included in the stack trace, however in chrome I'm seeing every line of the error message with "anonymous" stuck at the front in a meaningless way:
settings = jQuery.extend({
{anonymous}()@ statusTextEl: null,
{anonymous}()@ statusBarEl: null,
{anonymous}()@ errorDelay: 999, // handles 404-Errors in IE
{anonymous}()@ simultaneousCacheLoading: 2
{anonymous}()@ }, settings);
{anonymous}()@ var allImgs = [],
{anonymous}()@ loaded = 0,
{anonymous}()@ imgUrls = [],
{anonymous}()@ thisSheetRules,
{anonymous}()@ errorTimer;
... snipped some lines here ...
{anonymous}()@ }
parseCSS(document.styleSheets);
{anonymous}()@ return imgUrls;
{anonymous}()@} has no method 'blorf'
I tested this in at least Firefox and Chrome, and the stack trace is completely uninformative if called from window.onerror. I guess this makes sense, since by the time the error has reached the onerror handler, the stack has already been unrolled and discarded. Since there's no error object that can be used, printStackTrace creates it's own error object. Since this is now the new point where the error has been thrown, and since no previous stack trace is available anyway, the stack trace is now filled with only stack frames from within the stacktrace.js function.
If I'm doing something something wrong and don't know about it, please let me know.
My code:
window.onerror = function() {
alert(printStackTrace({guess:true}).join("\n");
}
function a() {
b();
}
function b() {
c();
}
a(); // Throws an error since c is undefined
Output in Firefox:
createException()@http://localhost:4000/stacktrace.js:42
run(null)@http://localhost:4000/stacktrace.js:27
printStackTrace([object Object])@http://localhost:4000/stacktrace.js:18
onerror("c is not defined","http://localhost:4000/test.js",6)@http://localhost:4000/test.html:5
Note that the last line in the trace above seems to be not from the stack, but from the arguments of the window.onerror handler, which I could have got anyway without printStackTrace by inspecting the arguments object in the handler. There's no mention of a or b that lead up to c.
Output in Chrome:
Object.createException (http://localhost:4000/stacktrace.js:42:18)
Object.run (http://localhost:4000/stacktrace.js:27:25)
printStackTrace (http://localhost:4000/stacktrace.js:18:62)
onerror()@http://localhost:4000/test.html:5:11
I tried moving a, and b to a separate js file included with a <script>
tag, to see if {guess:true}
will be able to help by reading the source, but that didn't help.
Am I doing something wrong?
Getting a warning when installing using bower
$ bower install
bower stacktrace#0.5.3 not-cached git://github.com/eriwen/javascript-stacktrace.git#0.5.3
bower stacktrace#0.5.3 resolve git://github.com/eriwen/javascript-stacktrace.git#0.5.3
bower stacktrace#0.5.3 download https://github.com/eriwen/javascript-stacktrace/archive/v0.5.3.tar.gz
bower stacktrace#0.5.3 progress received 3.0MB of 5.7MB downloaded, 53%
bower stacktrace#0.5.3 progress received 3.6MB of 5.7MB downloaded, 62%
bower stacktrace#0.5.3 progress received 4.1MB of 5.7MB downloaded, 72%
bower stacktrace#0.5.3 progress received 4.7MB of 5.7MB downloaded, 82%
bower stacktrace#0.5.3 progress received 5.3MB of 5.7MB downloaded, 93%
bower stacktrace#0.5.3 progress received 5.7MB of 5.7MB downloaded, 99%
bower stacktrace#0.5.3 extract archive.tar.gz
bower stacktrace#0.5.3 mismatch Version declared in the json (0.5.2) is different than the resolved one (0.5.3)
bower stacktrace#0.5.3 resolved git://github.com/eriwen/javascript-stacktrace.git#0.5.3
bower stacktrace#0.5.3 install stacktrace#0.5.3
stacktrace#0.5.3 project\ext\stacktrace
I notice that bower is using https://github.com/eriwen/javascript-stacktrace and not the new stacktracejs account. Is that related?
Might be of interest, https://github.com/occ/TraceKit
I've been doing plenty of work on the project, along with @occ
TraceKit supports IE. (to the extent possible)
When we combine efforts, we just get more collective bug fixes and features. Both projects basically do the same thing, so I think it makes sense to do this eventually.
The stacktrace parsing is returning different results for Chrome and Firefox.
The Chrome parsing is leaving ()s around the filename:
For example:
Chrome:
["testError (file://localhost/Users/ali/Desktop/test.html:6:5)", "{anonymous}()@file://localhost/Users/ali/Desktop/test.html:12:1"]
Firefox:
["testError@file:///Users/ali/Desktop/test.html:6", "{anonymous}()@file:///U...li/Desktop/test.html:12"]
Is this expected or should it be returning consistent results for each browser?
I captured some production log, in one example user used IE9, and the logged message is
at {anonymous}() at printStackTrace() at {anonymous}(#object,"error","") at {anonymous}(#object,[#object...""]) at d(12031,"",#object,"") at {anonymous}()
Any clue how to interpret "anonymous"?
Chrome 27.0.1453.116 m
When I use printStackTrace({e: error})
on anonymous functions the line numbers need to be smaller by one.
Can you reproduce this on your end?
Run this:
<html><head><script src="stacktrace.js"></script>
<script>
function recurse(b) {
if (b) {
recurse(false);
} else {
document.body.appendChild(document.createTextNode(printStackTrace()));
}
}
window.onload = function() {
recurse(true);
}
</script>
</head>
<body></body>
</html>
Actual: "{anonymous}(),printStackTrace(),recurse(false),recurse(false),recurse(false),recurse(false),recurse(false),recurse(false),recurse(false),recurse(false)"
Expected: "{anonymous}(),printStackTrace(),recurse(true),recurse(false)"
I think this is endemic to the code's "other" approach: arguments.caller just doesn't provide enough information to unwind the stack when the caller's caller is the same function; all further ancestor callers are lost when any function calls itself.
Running function instrumentation test case at http://eriwen.com/js/stacktrace/testcase4.html loses bottom of stack in Chrome 12.
See test for details.
Result of
var guess = (options && options.guess) ? options.guess : true;
will always be true for boolean options.guess (even for {guess:false}).
Causes it to fail as a chrome extension content script.
Changing the Ø character in line 5:
Øyvind Sean Kinsey http://kinsey.no/blog (2010)
Fixes the issue.
focus.xd.js seems to do some hackery with the window object that causes printStackTrace() to fail when it tries to cause an Error - (0)(); This failure is silent because all errors within window.onerror functions fail silently to prevent an infinite loop of, um, Errors.
See http://eriwen.com/examples/silentfail.html for an example.
It seems that using "throw 'error'" instead of (0)(); circumvents this problem, at the cost of losing our Error object that produces better stacktraces in good browsers.
In strict mode, use of argument.caller throws an exception. This means that if there is strict mode code anywhere in the call stack, printStackTrace fails. Here's a jsfiddle that illustrates this: http://jsfiddle.net/SVN4D/ (I'm passing an integer as the error object to force IE-style stacktrace generation, since the implementation for webkit et al doesn't rely on argument.caller).
Instead of throwing an exception, I think it would make more sense to return as much of the call stack as we can, and then have the last entry in the array be something like 'error: cannot read strict mode stacktraces for this browser' or something.
The bookmarklet is broken.
This happens because the js file is unable to load (http://eriwen.com/js/stacktrace.js).
Please bring back that file.
stacktrace.js is dropping the exception message unexpectedly when called from within a timer.
Testcase: http://jsfiddle.net/7bkKL/1/
Version tested: 82fdc86 (latest as of today)
Browser: Chrome 29.0.1547.57 m
If you replace printStackTrace() by "throw error" you will see the full stack-trace printed without the exception message.
In Firefox 6 and a recent check-out of javascript-stacktrace, Firefox silently leaves execution of printStackTrace() prematurely
Here is a reduced code snippet that exhibits the described behavior:
// Somewhere error gets thrown
throw 'An error occured';
window.onerror = function (errorMsg, url, lineNumber) {
alert(errorMsg + url + lineNumber);
// Previous line gets executed
var trace;
try {
// Firefox enters printStackTrace. Leaves silently somewhere in there
trace = printStackTrace().join('\n\n\t');
// Execution does not arrive here (as evidenced in debugger)
}
catch (e) {
// nothing gets thrown/caught in Firefox
// error console empty (the original uncaught exception is logged)
}
// Execution does not arrive here
// (as evidenced in debugger and actual browser window)
alert(trace);
return true;
}
See http://eriwen.com/js/stacktrace/testcase3.html in IE9 for details
The library should remove the parts of the stack that are stactrace.js internals - that won't be useful information to anybody.
I'd love to be able to call a method like getStackTrace which would return an array of frames instead of an array of strings. I have a custom model I need to populate and send to a service. Is there anyway to do this or can this feature be added!
What do you think about using instead of
try {
var _err = undef << 1;
} catch (e) {
return e;
}
this sample:
try {
throw new Error("my error");
} catch (e) {
return e;
}
Seems to be happening again... see related #18
Chrome 28.0.1500.72
TypeError: Object #<Object> has no method 'undef'
at Object.printStackTrace.implementation.createException (http://cloud.github.com/downloads/eriwen/javascript-stacktrace/stacktrace-min-0.4.js:2:202)
at Object.printStackTrace.implementation.run (http://cloud.github.com/downloads/eriwen/javascript-stacktrace/stacktrace-min-0.4.js:2:71)
at printStackTrace (http://cloud.github.com/downloads/eriwen/javascript-stacktrace/stacktrace-min-0.4.js:1:114)
at assertEquals (http://b2.int:8080/static/js/script.js:89:18)
at WidgetMealSelectionHelper.select_meal_id (http://b2.int:8080/order/choice:244:13)
at Number.<anonymous> (http://b2.int:8080/order/choice:263:25)
at Function.b.extend.each (http://b2.int:8080/static/js/libs/jquery-1.9.1.min.js:3:5257)
at WidgetMealSelectionHelper.load_widget (http://b2.int:8080/order/choice:262:19)
at new WidgetMealSelectionHelper (http://b2.int:8080/order/choice:270:14)
at HTMLDocument.<anonymous> (http://b2.int:8080/order/choice:274:24) script.js:90
Uncaught assertEquals failed: 0 !== 2 script.js:91
Triggered with;
try {
assert(v1 == v2, err);
} catch(e) {
var tb = printStackTrace().join("\n\n");
console.log(tb);
throw e;
}
Chrome seems to report some functions as anonymous when they are not. For instance:
function f2() {
try {(0)();} catch(e) {
alert(e.stack);
}
}
f2();
reports a stack containing only an anonymous function.
This will not run if you do bower install stacktrace and is technically not a valid components.json file
Sorry, don't have the time at the moment to do an official pull request. I implemented nodejs support for stacktrace locally.
Code looks like this:
// identify nodejs runtime
if (global.process && global.process.title == 'node') {
return (this._mode = 'node');
} else
// get node stack trace
node: function(e) {
return e.stack.split('\n').slice(2);
},
Since commit 3843057
I get stack overflows in IE8. I tried to reproduce it in a Fiddle, but it's obviously related to one of the other includes in my page. Sorry I can't provide more info, but I have a test case which I can run if you want to see if you've fixed it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.