I came across this method to produce a Javascript stack trace (to fix an IE specific bug): http://pastie.org/253058.txt which sounds really useful, but when I call it, the stack trace I get is for the code of the script itself?!
Can this code be changed to produce a general stack trace? Or is there a better way to get a stack trace in IE?
(function () {
YOUR_NAMESPACE.getStackTrace = (function () {
var mode;
try {(0)()} catch (e) {
mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
}
switch (mode) {
case 'Firefox' : return function () {
try {(0)()} catch (e) {
return e.stack.replace(/^.*?\n/,'').
replace(/(?:\n@:0)?\s+$/m,'').
replace(/^\(/gm,'{anonymous}(').
split("\n");
}
};
case 'Opera' : return function () {
try {(0)()} catch (e) {
var lines = e.message.split("\n"),
ANON = '{anonymous}',
lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
i,j,len;
for (i=4,j=0,len=lines.length; i<len; i+=2) {
if (lineRE.test(lines[i])) {
lines[j++] = (RegExp.$3 ?
RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
ANON + RegExp.$2 + ':' + RegExp.$1) +
' -- ' + lines[i+1].replace(/^\s+/,'');
}
}
lines.splice(j,lines.length-j);
return lines;
}
};
default : return function () {
var curr = arguments.callee.caller,
FUNC = 'function', ANON = "{anonymous}",
fnRE = /function\s*([\w\-$]+)?\s*\(/i,
stack = [],j=0,
fn,args,i;
while (curr) {
fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
args = stack.slice.call(curr.arguments);
i = args.length;
while (i--) {
switch (typeof args[i]) {
case 'string' : args[i] = '"'+args[i].replace(/"/g,'\\"')+'"'; break;
case 'function': args[i] = FUNC; break;
}
}
stack[j++] = fn + '(' + args.join() + ')';
curr = curr.caller;
}
return stack;
};
}
})();
This getStackTrace()
function creates the stack trace of the function from which you've called getStackTrace()
. It does not create the stack trace of an error that you've caught. For example, you'd use it to try to figure out how a specific function is being called:
function foo() {
// debug how this is being called
alert(YOUR_NAMESPACE.getStackTrace());
}
Or to add some more detail to an error you raise:
function foo() {
// signal something went wrong
var error = new Error("error in foo");
if (!error.stack)
error.stack = YOUR_NAMESPACE.getStackTrace();
throw error;
}
You can not use it like this:
try {
foo();
} catch (e) {
alert(YOUR_NAMESPACE.getStackTrace(e));
}
Here's a good rundown of what stack information you can get -- and from which browsers -- when an error occurs: Three Painful Ways to Obtain a Stack Trace in Javascript (Archive.org link replacing dead link)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With