Làm cách nào tôi có thể có được dấu vết ngăn xếp JavaScript khi tôi ném ngoại lệ?


519

Nếu tôi tự ném một ngoại lệ JavaScript (ví dụ throw "AArrggg":), làm cách nào tôi có thể theo dõi ngăn xếp (trong Fireorms hoặc cách khác)? Ngay bây giờ tôi chỉ nhận được tin nhắn.

chỉnh sửa : Như nhiều người bên dưới đã đăng, có thể lấy theo dõi ngăn xếp cho một ngoại lệ JavaScript nhưng tôi muốn nhận được theo dõi ngăn xếp cho các ngoại lệ của mình . Ví dụ:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}

Khi foođược gọi, tôi muốn có được một vết đống trong đó bao gồm các cuộc gọi đến foo, bar, bar.



Bug vẫn đang mở trên trình theo dõi lỗi Fireorms kể từ năm 2008: code.google.com/p/forms/issues/detail?id=1260 - đánh dấu sao!
Miller Medeiros

13
Câu trả lời phải là "ném Lỗi mới ('cholrgh');" xem trang được viết độc đáo này: dev Dùt.com / 2011/12/22 / a
súc sắc tao nhã

1
(2013) Bây giờ bạn có thể nhận được các dấu vết ngăn xếp trong Fireorms trên Firefox ngay cả khi chỉ đơn giản throw 'arrrgh';và chúng có vẻ giống như với throw new Error('arrrgh');. throw new Error('arrrgh');Tuy nhiên, trình gỡ lỗi Chrome vẫn cần như đã nêu (nhưng Chrome dường như cung cấp các dấu vết chi tiết hơn nhiều).
user56reinstatemonica8

26
@ChetanSastry Tôi đã tìm kiếm 'dấu vết ngăn xếp javascript' và đây là kết quả đầu tiên
David Sykes

Câu trả lời:


756

Chỉnh sửa 2 (2017):

Trong tất cả các trình duyệt hiện đại, bạn chỉ cần gọi: console.trace(); (Tham khảo MDN)

Chỉnh sửa 1 (2013):

Một giải pháp tốt hơn (và đơn giản hơn) như được chỉ ra trong các nhận xét về câu hỏi ban đầu là sử dụng thuộc stacktính của một Errorđối tượng như vậy:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Điều này sẽ tạo ra đầu ra như thế này:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Đặt tên của chức năng gọi cùng với URL, chức năng gọi của nó, v.v.

Bản gốc (2009):

Một phiên bản sửa đổi của đoạn trích này có thể giúp ích phần nào:

function stacktrace() { 
  function st2(f) {
    return !f ? [] : 
        st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + f.arguments.join(',') + ')']);
  }
  return st2(arguments.callee.caller);
}

11
Tôi không chắc tại sao điều này không được bình chọn nhiều hơn - các câu trả lời khác không phù hợp với tôi. BTW, đảm bảo không coi các đối số là một mảng (đoạn trích được cập nhật tại đây: gist.github.com/965603 )
ripper234

1
không hoạt động trong chrome, tacktrace (): [Ngoại lệ: TypeError: Object # <Object> không có phương thức
hetaoblog

3
xem bình luận về câu hỏi ban đầu: bạn không cần mã tùy chỉnh, chỉ cần sử dụng "throw new Error ('cholrgh')"
Joshua Richardson

16
Error.stack không được xác định trong IE, chỉ hoạt động trong chrome và Mozilla firefox
Philipp Munin

4
Lưu ý rằng callerhiện không được chấp nhận và calleebị xóa khỏi chế độ nghiêm ngặt ES5. Đây là lý do tại sao stackoverflow.com/questions/103598/
Mạnh

187

Lưu ý rằng chromium / chrome (các trình duyệt khác sử dụng V8) và Firefox cũng có giao diện thuận tiện để có được một stacktrace thông qua thuộc tính stack trên các đối tượng Error .

try {
   // Code throwing an exception
} catch(e) {
  console.log(e.stack);
}

Nó áp dụng cho các trường hợp ngoại lệ cơ bản cũng như cho những người bạn tự ném. (Được coi là bạn sử dụng lớp Error, dù sao đây cũng là một cách thực hành tốt).

Xem chi tiết về tài liệu V8


12
Firefox cũng hỗ trợ .stacktài sản.
kennytm

2
Tôi ước tôi có thể nâng cấp 100 lần! Cảm ơn bạn Jocelyn. Nó thực sự giúp ích rất nhiều
safrazik

1
bạn cũng có thể sử dụng console.error(e.stack);để nó trông giống như một thông báo ngoại lệ mặc định
Bruno Peres

80

Trong Firefox, có vẻ như bạn không cần phải ném ngoại lệ. Nó đủ để làm

e = new Error();
console.log(e.stack);

Hoạt động trong các ứng dụng di động (được xây dựng bằng JQM).
Samik R

Cũng hoạt động trong Chromium (phiên bản 43).
Andy Beverley

Trong Firefox 59, nó không hoạt động khi được gọi thông qua window.onerror, nó hiển thị một ngăn xếp gần như trống rỗng chỉ có onerrorchức năng.
Code4R7

Thậm chí tốt hơn, bạn có thể làm: console.log(new Error().stack)> :(> :(> :(
Andrew

25

Nếu bạn có fireorms, sẽ có một tùy chọn trên tất cả các lỗi trong tab script. Khi tập lệnh đã đạt đến điểm dừng của bạn, bạn có thể nhìn vào cửa sổ ngăn xếp của fireorms:

ảnh chụp màn hình


5
Hrm, dường như không hoạt động. Nó ngăn tôi trong trình gỡ lỗi về các lỗi được tạo ra bởi Javascript (ví dụ: các lỗi biến không xác định), nhưng khi tôi đưa ra các ngoại lệ của riêng mình, tôi vẫn không nhận được bất cứ điều gì ngoài thông báo "Không ngoại lệ".
David Wolever

11

Một giải pháp tốt (và đơn giản) như được chỉ ra trong các nhận xét về câu hỏi ban đầu là sử dụng thuộc stacktính của một Errorđối tượng như vậy:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Điều này sẽ tạo ra đầu ra như thế này:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Đặt tên của chức năng gọi cùng với URL và số đường dây, chức năng gọi của nó, v.v.

Tôi có một giải pháp thực sự công phu và đẹp mắt mà tôi đã nghĩ ra cho một dự án mà tôi hiện đang làm và tôi đã trích xuất và làm lại nó một chút để được khái quát. Đây là:

(function(context){
    // Only global namespace.
    var Console = {
        //Settings
        settings: {
            debug: {
                alwaysShowURL: false,
                enabled: true,
                showInfo: true
            },
            stackTrace: {
                enabled: true,
                collapsed: true,
                ignoreDebugFuncs: true,
                spacing: false
            }
        }
    };

    // String formatting prototype function.
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var s = this.toString(),
                args = typeof arguments[0],
                args = (("string" == args || "number" == args) ? arguments : arguments[0]);
            if (!arguments.length)
                return s;
            for (arg in args)
                s = s.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
            return s;
        }
    }

    // String repeating prototype function.
    if (!String.prototype.times) {
        String.prototype.times = function () {
            var s = this.toString(),
                tempStr = "",
                times = arguments[0];
            if (!arguments.length)
                return s;
            for (var i = 0; i < times; i++)
                tempStr += s;
            return tempStr;
        }
    }

    // Commonly used functions
    Console.debug = function () {
        if (Console.settings.debug.enabled) {
            var args = ((typeof arguments !== 'undefined') ? Array.prototype.slice.call(arguments, 0) : []),
                sUA = navigator.userAgent,
                currentBrowser = {
                    firefox: /firefox/gi.test(sUA),
                    webkit: /webkit/gi.test(sUA),
                },
                aLines = Console.stackTrace().split("\n"),
                aCurrentLine,
                iCurrIndex = ((currentBrowser.webkit) ? 3 : 2),
                sCssBlack = "color:black;",
                sCssFormat = "color:{0}; font-weight:bold;",
                sLines = "";

            if (currentBrowser.firefox)
                aCurrentLine = aLines[iCurrIndex].replace(/(.*):/, "$1@").split("@");
            else if (currentBrowser.webkit)
                aCurrentLine = aLines[iCurrIndex].replace("at ", "").replace(")", "").replace(/( \()/gi, "@").replace(/(.*):(\d*):(\d*)/, "$1@$2@$3").split("@");

            // Show info if the setting is true and there's no extra trace (would be kind of pointless).
            if (Console.settings.debug.showInfo && !Console.settings.stackTrace.enabled) {
                var sFunc = aCurrentLine[0].trim(),
                    sURL = aCurrentLine[1].trim(),
                    sURL = ((!Console.settings.debug.alwaysShowURL && context.location.href == sURL) ? "this page" : sURL),
                    sLine = aCurrentLine[2].trim(),
                    sCol;

                if (currentBrowser.webkit)
                    sCol = aCurrentLine[3].trim();

                console.info("%cOn line %c{0}%c{1}%c{2}%c of %c{3}%c inside the %c{4}%c function:".format(sLine, ((currentBrowser.webkit) ? ", column " : ""), ((currentBrowser.webkit) ? sCol : ""), sURL, sFunc),
                             sCssBlack, sCssFormat.format("red"),
                             sCssBlack, sCssFormat.format("purple"),
                             sCssBlack, sCssFormat.format("green"),
                             sCssBlack, sCssFormat.format("blue"),
                             sCssBlack);
            }

            // If the setting permits, get rid of the two obvious debug functions (Console.debug and Console.stackTrace).
            if (Console.settings.stackTrace.ignoreDebugFuncs) {
                // In WebKit (Chrome at least), there's an extra line at the top that says "Error" so adjust for this.
                if (currentBrowser.webkit)
                    aLines.shift();
                aLines.shift();
                aLines.shift();
            }

            sLines = aLines.join(((Console.settings.stackTrace.spacing) ? "\n\n" : "\n")).trim();

            trace = typeof trace !== 'undefined' ? trace : true;
            if (typeof console !== "undefined") {
                for (var arg in args)
                    console.debug(args[arg]);

                if (Console.settings.stackTrace.enabled) {
                    var sCss = "color:red; font-weight: bold;",
                        sTitle = "%c Stack Trace" + " ".times(70);

                    if (Console.settings.stackTrace.collapsed)
                        console.groupCollapsed(sTitle, sCss);
                    else
                        console.group(sTitle, sCss);

                    console.debug("%c" + sLines, "color: #666666; font-style: italic;");

                    console.groupEnd();
                }
            }
        }
    }
    Console.stackTrace = function () {
        var err = new Error();
        return err.stack;
    }

    context.Console = Console;
})(window);

Hãy xem thử trên GitHub (hiện là v1.2)! Bạn có thể sử dụng nó như thế nào Console.debug("Whatever");và tùy theo cài đặt Console, in đầu ra và dấu vết ngăn xếp (hoặc chỉ là thông tin đơn giản / không có gì thêm). Đây là một ví dụ:

Console.js

Hãy chắc chắn để chơi xung quanh với các cài đặt trong Consoleđối tượng! Bạn có thể thêm khoảng cách giữa các dòng của dấu vết và tắt hoàn toàn. Đây là với Console.tracethiết lập để false:

Không dấu vết

Bạn thậm chí có thể tắt bit thông tin đầu tiên được hiển thị (đặt Console.settings.debug.showInfothành false) hoặc tắt hoàn toàn gỡ lỗi (được đặt Console.settings.debug.enabledthành false) để bạn không bao giờ phải nhận xét lại câu lệnh gỡ lỗi nữa! Chỉ cần để chúng vào và điều này sẽ không làm gì cả.


10

Tôi không nghĩ có bất cứ thứ gì được xây dựng trong đó bạn có thể sử dụng tuy nhiên tôi đã tìm thấy rất nhiều ví dụ về những người tự lăn lộn.


À, cảm ơn - liên kết đầu tiên có vẻ như nó có thể làm được (mặc dù việc thiếu hỗ trợ đệ quy có thể khiến nó không thể hoạt động được).
David Wolever

Vâng, tôi đã không thấy bất kỳ đệ quy hỗ trợ nào trong cái nhìn đầu tiên. Tôi sẽ tò mò xem liệu có một giải pháp tốt cho điều đó.
Mark Biek

1
Tôi nghĩ rằng liên kết thứ hai nên hỗ trợ đệ quy cho Firefox và Opera vì nó sử dụng theo dõi ngăn xếp lỗi thay vì xây dựng thủ công bằng cách sử dụng biến đối số. Tôi rất muốn nghe nếu bạn tìm thấy một giải pháp trình duyệt chéo cho vấn đề đệ quy (bài viết đầu tiên là của tôi). :)
Helephant

Người trợ giúp: Thứ hai sẽ không hoạt động ở đây bởi vì, khi tôi bắt được ngoại lệ, đó là "chuỗi" (nghĩa là không có "e.stack"): foo = function () {throw "Arg"; } thử {foo (); } Catch (e) {/ * typeof e == "chuỗi" * /} Có lẽ tôi đang ném nhầm? (bắt đầu bài ca bắt buộc về cách hướng dẫn Javascript ngu ngốc ...)
David Wolever

Cố gắng ném một đối tượng : throw { name: 'NameOfException', message: 'He's dead, Jim' }.
Aaron Digulla

7

Bạn có thể truy cập các thuộc tính stack( stacktracetrong Opera) của một Errorthể hiện ngay cả khi bạn đã ném nó. Vấn đề là, bạn cần chắc chắn rằng bạn sử dụng throw new Error(string)(đừng quên cái mới thay vì throw string.

Thí dụ:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}

stacktrace không hoạt động trong Opera. Tôi thậm chí không thể tìm thấy một cái gì đó về nó.
NVI

@NV: Có vẻ như stacktrace không phải do lỗi do người dùng tạo nên bạn nên thực hiện việc này thay vào đó: thử {0 ++} Catch (e) {myStackTrace = e.stack || e.stacktrace}
Eli Gray


7

Điều này sẽ cung cấp dấu vết ngăn xếp (dưới dạng chuỗi chuỗi) cho Chrome, Opera, Firefox và IE10 + hiện đại

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Sử dụng:

console.log(getStackTrace().join('\n'));

Nó loại trừ khỏi ngăn xếp cuộc gọi của chính nó cũng như tiêu đề "Lỗi" được Chrome và Firefox sử dụng (nhưng không phải IE).

Nó không nên sập trên các trình duyệt cũ hơn mà chỉ trả về mảng trống. Nếu bạn cần giải pháp phổ quát hơn, hãy xem stacktrace.js . Danh sách các trình duyệt được hỗ trợ của nó thực sự ấn tượng nhưng theo tôi thì nó rất lớn cho nhiệm vụ nhỏ đó, nó được dành cho: 37Kb văn bản rút gọn bao gồm tất cả các phụ thuộc.


7

Một bản cập nhật cho câu trả lời của Eugene: Đối tượng lỗi phải được ném để IE (phiên bản cụ thể?) Để đưa vào stacktài sản. Dưới đây sẽ hoạt động tốt hơn ví dụ hiện tại của anh ấy và nên tránh quay lại undefinedkhi ở trong IE.

function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.stack;
  }
}

Lưu ý 1: Loại điều này chỉ nên được thực hiện khi gỡ lỗi và bị vô hiệu hóa khi trực tiếp, đặc biệt nếu được gọi thường xuyên. Lưu ý 2: Điều này có thể không hoạt động trong tất cả các trình duyệt, nhưng dường như hoạt động trong FF và IE 11, phù hợp với nhu cầu của tôi.


6

một cách để có được dấu vết ngăn xếp thực sự trên Fireorms là tạo ra một lỗi thực sự như gọi một hàm không xác định:

function foo(b){
  if (typeof b !== 'string'){
    // undefined Error type to get the call stack
    throw new ChuckNorrisError("Chuck Norris catches you.");
  }
}

function bar(a){
  foo(a);
}

foo(123);

Hoặc sử dụng console.error()theo sau bởi một throwtuyên bố kể từ khi console.error()hiển thị dấu vết ngăn xếp.


4

Mã polyfill này hoạt động trong các trình duyệt hiện đại (2017) (IE11, Opera, Chrome, FireFox, Yandex):

printStackTrace: function () {
    var err = new Error();
    var stack = err.stack || /*old opera*/ err.stacktrace || ( /*IE11*/ console.trace ? console.trace() : "no stack info");
    return stack;
}

Câu trả lời khác:

function stackTrace() {
  var err = new Error();
  return err.stack;
}

không hoạt động trong IE 11!

Sử dụng argument.callee.caller - không hoạt động ở chế độ nghiêm ngặt trong bất kỳ trình duyệt nào!


3

Trong Google Chrome (phiên bản 19.0 trở lên), chỉ cần ném một ngoại lệ hoạt động hoàn hảo. Ví dụ:

/* file: code.js, line numbers shown */

188: function fa() {
189:    console.log('executing fa...');
190:    fb();
191: }
192:
193: function fb() {
194:    console.log('executing fb...');
195:    fc()
196: }
197:
198: function fc() {
199:    console.log('executing fc...');
200:    throw 'error in fc...'
201: }
202:
203: fa();

sẽ hiển thị theo dõi ngăn xếp ở đầu ra giao diện điều khiển của trình duyệt:

executing fa...                         code.js:189
executing fb...                         code.js:194
executing fc...                         cdoe.js:199
/* this is your stack trace */
Uncaught error in fc...                 code.js:200
    fc                                  code.js:200
    fb                                  code.js:195
    fa                                  code.js:190
    (anonymous function)                code.js:203

Hy vọng điều này giúp đỡ.


3

chức năng:

function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}

trường hợp sử dụng:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }

2
<script type="text/javascript"
src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

đoạn script này sẽ hiển thị lỗi


2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}

2
Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
Vịt Donald

1

Loại muộn của bữa tiệc, nhưng, đây là một giải pháp khác, tự động phát hiện nếu argument.callee có sẵn và sử dụng Error (). Stack mới nếu không. Đã thử nghiệm trong chrome, safari và firefox.

2 biến thể - stackFN (n) cung cấp cho bạn tên của hàm n cách xa người gọi ngay lập tức và stackArray () cung cấp cho bạn một mảng, stackArray () [0] là người gọi ngay lập tức.

Dùng thử tại http://jsfiddle.net/qcP9y/6/

// returns the name of the function at caller-N
// stackFN()  = the immediate caller to stackFN
// stackFN(0) = the immediate caller to stackFN
// stackFN(1) = the caller to stackFN's caller
// stackFN(2) = and so on
// eg console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
function stackFN(n) {
    var r = n ? n : 0, f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (r-- >= 0) {
            tl(")");
        }
        tl(" at ");
        tr("(");
        return s;
    } else {
        if (!avail) return null;
        s = "f = arguments.callee"
        while (r>=0) {
            s+=".caller";
            r--;   
        }
        eval(s);
        return f.toString().split("(")[0].trim().split(" ")[1];
    }
}
// same as stackFN() but returns an array so you can work iterate or whatever.
function stackArray() {
    var res=[],f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (s.indexOf(")")>=0) {
            tl(")");
            s2= ""+s;
            tl(" at ");
            tr("(");
            res.push(s);
            s=""+s2;
        }
    } else {
        if (!avail) return null;
        s = "f = arguments.callee.caller"
        eval(s);
        while (f) {
            res.push(f.toString().split("(")[0].trim().split(" ")[1]);
            s+=".caller";
            eval(s);
        }
    }
    return res;
}


function apple_makes_stuff() {
    var retval = "iPhones";
    var stk = stackArray();

    console.log("function ",stk[0]+"() was called by",stk[1]+"()");
    console.log(stk);
    console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
    return retval;
}



function apple_makes (){
    return apple_makes_stuff("really nice stuff");
}

function apple () {
    return apple_makes();
}

   apple();

1

Bạn có thể sử dụng thư viện này http://www.stacktracejs.com/ . Nó rất tốt

Từ tài liệu

Bạn cũng có thể vượt qua Lỗi của chính mình để nhận một stacktrace không khả dụng trong IE hoặc Safari 5-

<script type="text/javascript" src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

Nguồn được liên kết https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.jslà một phiên bản cũ, phiên bản ổn định mới nhất (khớp với đoạn mã) ở đây:https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.js
Frederic Leitenberger

1

Dưới đây là câu trả lời cung cấp cho bạn hiệu suất tối đa (IE 6+) và khả năng tương thích tối đa. Tương thích với IE 6!

    function stacktrace( log_result ) {
    	var trace_result;
    // IE 6 through 9 compatibility
    // this is NOT an all-around solution because
    // the callee property of arguments is depredicated
    /*@cc_on
    	// theese fancy conditinals make this code only run in IE
    	trace_result = (function st2(fTmp) {
    		// credit to Eugene for this part of the code
    		return !fTmp ? [] :
    			st2(fTmp.caller).concat([fTmp.toString().split('(')[0].substring(9) + '(' + fTmp.arguments.join(',') + ')']);
    	})(arguments.callee.caller);
    	if (log_result) // the ancient way to log to the console
    		Debug.write( trace_result );
    	return trace_result;
    @*/
    	console = console || Console;	// just in case
    	if (!(console && console.trace) || !log_result){
    		// for better performance in IE 10
    		var STerror=new Error();
    		var unformated=(STerror.stack || STerror.stacktrace);
    		trace_result = "\u25BC console.trace" + unformated.substring(unformated.indexOf('\n',unformated.indexOf('\n'))); 
    	} else {
    		// IE 11+ and everyone else compatibility
    		trace_result = console.trace();
    	}
    	if (log_result)
    		console.log( trace_result );
    	
    	return trace_result;
    }
// test code
(function testfunc(){
	document.write( "<pre>" + stacktrace( false ) + "</pre>" );
})();


0

Dễ dàng có được một dấu vết ngăn xếp trên Firefox hơn là trên IE nhưng về cơ bản đây là những gì bạn muốn làm:

Gói đoạn mã "có vấn đề" trong khối thử / bắt:

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}

Nếu bạn sẽ kiểm tra nội dung của đối tượng "lỗi" thì nó chứa các trường sau:

e.fileName: Tệp / trang nguồn có sự cố xuất phát từ e.lineNumber: Số dòng trong tệp / trang nơi phát sinh sự cố e.message: Một thông báo đơn giản mô tả loại lỗi xảy ra e.name: Loại lỗi đã xảy ra, trong ví dụ trên phải là 'TypeError' e.stack: Chứa dấu vết ngăn xếp gây ra ngoại lệ

Tôi hy vọng điều này sẽ giúp bạn ra ngoài.


1
Sai lầm. Anh ta đang cố gắng để bắt ngoại lệ của riêng mình. Nếu anh ta ném "asdfg", anh ta sẽ nhận được đối tượng chuỗi, không phải là đối tượng ngoại lệ. Anh ta không cố gắng để bắt ngoại lệ tích hợp.
Ivan Vučica

0

Tôi đã phải điều tra một đệ quy vô tận trong smartgwt với IE11, vì vậy để điều tra sâu hơn, tôi cần một dấu vết ngăn xếp. Vấn đề là, tôi không thể sử dụng bảng điều khiển dev, vì việc tái tạo khó khăn hơn theo cách đó.
Sử dụng như sau trong một phương pháp javascript:

try{ null.toString(); } catch(e) { alert(e.stack); }

cảnh báo ((Lỗi mới ()). stack);
người làm giàu giàu có vào

0

Ồ - tôi không thấy một người nào trong 6 năm đề nghị chúng tôi kiểm tra trước để xem nếu stack có sẵn trước khi sử dụng không! Điều tồi tệ nhất bạn có thể làm trong một trình xử lý lỗi là ném lỗi vì gọi một cái gì đó không tồn tại.

Như những người khác đã nói, trong khi stackhầu hết an toàn để sử dụng thì bây giờ nó không được hỗ trợ trong IE9 hoặc sớm hơn.

Tôi ghi lại các lỗi không mong muốn của mình và theo dõi ngăn xếp là khá cần thiết. Để được hỗ trợ tối đa trước tiên tôi kiểm tra xem có Error.prototype.stacktồn tại không và có phải là một hàm không. Nếu vậy thì an toàn để sử dụng error.stack.

        window.onerror = function (message: string, filename?: string, line?: number, 
                                   col?: number, error?: Error)
        {
            // always wrap error handling in a try catch
            try 
            {
                // get the stack trace, and if not supported make our own the best we can
                var msg = (typeof Error.prototype.stack == 'function') ? error.stack : 
                          "NO-STACK " + filename + ' ' + line + ':' + col + ' + message;

                // log errors here or whatever you're planning on doing
                alert(msg);
            }
            catch (err)
            {

            }
        };

Chỉnh sửa: Dường như stacklà một thuộc tính và không phải là một phương thức bạn có thể gọi nó một cách an toàn ngay cả trên các trình duyệt cũ hơn. Tôi vẫn còn bối rối bởi vì tôi khá chắc chắn rằng việc kiểm tra Error.prototypeđã làm việc cho tôi trước đây và bây giờ thì không - vì vậy tôi không chắc chuyện gì đang xảy ra.


0

Sử dụng console.error(e.stack)Firefox chỉ hiển thị stacktrace trong nhật ký, Chrome cũng hiển thị thông báo. Điều này có thể là một bất ngờ xấu nếu tin nhắn có chứa thông tin quan trọng. Luôn luôn đăng nhập cả hai.


0

Thử xem

throw new Error('some error here')

Điều này hoạt động khá tốt cho chrome:

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.