最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

debugging - Javascript Stack Trace in IE (or maybe just a simple Javascript error) - Stack Overflow

programmeradmin3浏览0评论

I came across this method to produce a Javascript stack trace (to fix an IE specific bug): .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;
    };
}

})();

I came across this method to produce a Javascript stack trace (to fix an IE specific bug): http://pastie/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;
    };
}

})();
Share Improve this question edited Aug 23, 2017 at 14:13 Scimonster 33.4k10 gold badges79 silver badges91 bronze badges asked Oct 1, 2009 at 8:55 GavinGavin 2,3513 gold badges19 silver badges23 bronze badges 2
  • What do you mean "for the code of the script itself"? The call to the stack trace code should be at the top of the stack trace, but then under that is your caller, right? – Jeremy Stein Commented Oct 1, 2009 at 14:47
  • Hi Jeremy, That may be the case. I'm displaying the text using alert(), but the text I'm getting back ends in '...' so maybe it's too big and the actual trace is just below this. Is it possible to remove the 'trace function' call from the output? – Gavin Commented Oct 1, 2009 at 16:10
Add a ment  | 

2 Answers 2

Reset to default 12

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 link replacing dead link)

You might be better off using IE 8's built-in debugger.

发布评论

评论列表(0)

  1. 暂无评论