Bagaimana saya bisa mendapatkan jejak tumpukan JavaScript ketika saya melempar pengecualian?

519

Jika saya melempar sendiri pengecualian JavaScript (mis., throw "AArrggg"), Bagaimana saya bisa mendapatkan jejak stack (di Firebug atau yang lain)? Saat ini saya baru saja menerima pesannya.

sunting : Seperti banyak orang di bawah ini telah memposting, dimungkinkan untuk mendapatkan jejak stack untuk pengecualian JavaScript tapi saya ingin mendapatkan jejak stack untuk pengecualian saya . Sebagai contoh:

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

Ketika foodisebut, saya ingin mendapatkan setumpuk jejak yang mencakup panggilan ke foo, bar, bar.

David Wolever
sumber
1
kemungkinan duplikat jejak tumpukan pengecualian Javascript
ripper234
Bug masih terbuka di pelacak bug Firebug sejak 2008: code.google.com/p/fbug/issues/detail?id=1260 - beri bintang!
Miller Medeiros
13
Jawabannya harus "throw new Error ('arrrgh');" lihat halaman yang ditulis dengan indah ini: devthought.com/2011/12/22/a-string-is-not-an-error
dadu elegan
1
(2013) Anda sekarang bisa mendapatkan jejak tumpukan di Firebug di Firefox bahkan jika itu sederhana throw 'arrrgh';, dan mereka tampak sama dengan throw new Error('arrrgh');. Namun, debugger Chrome masih perlu throw new Error('arrrgh');seperti yang disebutkan (tetapi Chrome tampaknya memberikan jejak yang jauh lebih terperinci).
user56reinstatemonica8
26
@ ChetanSastry Saya mencari Google untuk 'jejak tumpukan javascript' dan ini adalah hasil pertama
David Sykes

Jawaban:

756

Edit 2 (2017):

Di semua browser modern, Anda cukup menelepon: console.trace(); (Referensi MDN)

Edit 1 (2013):

Solusi yang lebih baik (dan lebih sederhana) seperti yang ditunjukkan dalam komentar pada pertanyaan asli adalah dengan menggunakan stackproperti dari Errorobjek seperti:

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

Ini akan menghasilkan output seperti ini:

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

Memberi nama fungsi panggilan bersama dengan URL, fungsi panggilannya, dan sebagainya.

Asli (2009):

Versi modifikasi dari potongan ini mungkin dapat membantu:

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);
}
Eugene Morozov
sumber
11
Saya tidak yakin mengapa ini tidak lebih dipilih - jawaban lain tidak bekerja dengan baik untuk saya. BTW, pastikan untuk tidak memperlakukan argumen sebagai array (snippet yang diperbarui di sini: gist.github.com/965603 )
ripper234
1
tidak bekerja di chrome, tacktrace (): [Pengecualian: TypeError: Objek # <Object> tidak memiliki metode
hetaoblog
3
lihat komentar pada pertanyaan asli: Anda tidak perlu kode khusus, cukup gunakan "throw new Error ('arrrgh')"
Joshua Richardson
16
Error.stack tidak terdefinisi dalam IE, hanya berfungsi di chrome dan Mozilla firefox
Philipp Munin
4
Perhatikan bahwa callersekarang sudah usang dan calleedihapus dari mode ketat ES5. Inilah mengapa stackoverflow.com/questions/103598/…
PhilT
187

Perhatikan bahwa chromium / chrome (browser lain yang menggunakan V8), dan juga Firefox memiliki antarmuka yang nyaman untuk mendapatkan stacktrace melalui properti stack pada objek Error .

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

Ini berlaku untuk pengecualian dasar dan juga untuk yang Anda lemparkan sendiri. (Dianggap bahwa Anda menggunakan kelas Kesalahan, yang merupakan praktik yang baik).

Lihat detail pada dokumentasi V8

Jocelyn delalande
sumber
12
Firefox juga mendukung .stackproperti.
kennytm
2
Kuharap aku bisa menang 100 kali! Terima kasih, Jocelyn. Itu sangat banyak membantu
safrazik
1
Anda juga dapat menggunakannya console.error(e.stack);sehingga terlihat seperti pesan pengecualian default
Bruno Peres
80

Di Firefox tampaknya Anda tidak perlu membuang pengecualian. Itu cukup untuk dilakukan

e = new Error();
console.log(e.stack);
Justin L.
sumber
Bekerja di aplikasi seluler (dibangun menggunakan JQM) juga.
Samik R
Juga berfungsi di Chromium (versi 43).
Andy Beverley
Di Firefox 59 ini tidak berfungsi saat dipanggil via window.onerror, ini menunjukkan tumpukan yang hampir kosong hanya dengan onerrorfungsi.
Code4R7
Lebih baik lagi, Anda bisa melakukan: console.log(new Error().stack)> : (> :(> :(
Andrew
25

Jika Anda memiliki pembakar, ada opsi break pada semua kesalahan di tab skrip. Setelah skrip mencapai breakpoint Anda, Anda dapat melihat jendela stack firebug:

tangkapan layar

Helephant
sumber
5
Hrm, sepertinya itu tidak berhasil. Itu menghentikan saya dalam debugger tentang kesalahan yang diangkat oleh Javascript (misalnya, kesalahan variabel tidak terdefinisi), tetapi ketika saya melempar pengecualian saya sendiri, saya masih tidak mendapatkan apa pun selain pesan "Pengecualian tidak tertangkap".
David Wolever
11

Solusi yang baik (dan sederhana) seperti yang ditunjukkan dalam komentar pada pertanyaan asli adalah dengan menggunakan stackproperti dari Errorobjek seperti:

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

Ini akan menghasilkan output seperti ini:

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

Memberi nama fungsi panggilan bersama dengan URL dan nomor baris, fungsi panggilannya, dan sebagainya.

Saya memiliki solusi yang sangat rumit dan cantik yang telah saya buat untuk proyek yang sedang saya kerjakan dan saya telah mengekstrak dan mengerjakannya kembali sedikit untuk digeneralisasi. Ini dia:

(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);

Lihat di GitHub (saat ini v1.2)! Anda dapat menggunakannya seperti Console.debug("Whatever");dan itu akan, tergantung pada pengaturan dalam Console, mencetak output dan jejak tumpukan (atau hanya info sederhana / tidak ada tambahan sama sekali). Ini sebuah contoh:

Console.js

Pastikan untuk bermain-main dengan pengaturan di Consoleobjek! Anda dapat menambahkan spasi di antara garis-garis jejak dan mematikannya sepenuhnya. Ini dia dengan Console.traceset ke false:

Tanpa jejak

Anda bahkan dapat mematikan bit pertama info ditampilkan (set Console.settings.debug.showInfoke false) atau menonaktifkan debugging seluruhnya (set Console.settings.debug.enabledke false) sehingga Anda tidak perlu komentar keluar pernyataan debug lagi! Biarkan saja mereka dan ini tidak akan menghasilkan apa-apa.

Gabriel Nahmias
sumber
10

Saya tidak berpikir ada sesuatu yang dibangun di dalam yang dapat Anda gunakan, tetapi saya menemukan banyak contoh orang menggulung sendiri.

Mark Biek
sumber
Ah, terima kasih - tautan pertama di sana sepertinya dapat dilakukan (meskipun kurangnya dukungan rekursi dapat membuatnya tidak bisa digunakan).
David Wolever
Ya, saya tidak melihat ada yang mendukung rekursi pada pandangan pertama. Saya ingin tahu apakah ada solusi yang bagus untuk itu.
Mark Biek
1
Saya pikir tautan kedua harus mendukung rekursi untuk Firefox dan Opera karena menggunakan jejak tumpukan kesalahan daripada secara manual membangunnya menggunakan variabel argumen. Saya ingin mendengar jika Anda menemukan solusi lintas peramban untuk masalah rekursi (artikel pertama adalah milik saya). :)
Helephant
Helephant: Yang kedua tidak akan bekerja di sini karena, ketika saya menangkap pengecualian, itu adalah "string" (yaitu, tidak ada "e.stack"): foo = function () {throw "Arg"; } coba {foo (); } catch (e) {/ * typeof e == "string" * /} Mungkin saya salah melempar? (mulai kata-kata kasar wajib tentang betapa bodohnya Javascript tutorial ...)
David Wolever
Mencoba untuk melemparkan sebuah benda: throw { name: 'NameOfException', message: 'He's dead, Jim' }.
Aaron Digulla
7

Anda dapat mengakses properti stack( stacktracedalam Opera) dari Errorinstance bahkan jika Anda melemparkannya. Masalahnya, Anda harus memastikan Anda menggunakan throw new Error(string)(jangan lupa yang baru, bukan throw string.

Contoh:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
Eli Gray
sumber
stacktrace tidak berfungsi di Opera. Saya bahkan tidak dapat menemukan sesuatu tentang itu.
NVI
@NV: Sepertinya stacktrace tidak ada pada kesalahan yang dibuat pengguna jadi Anda harus melakukan ini sebagai gantinya: coba {0 ++} catch (e) {myStackTrace = e.stack || e.stacktrace}
Eli Gray
7

Ini akan memberikan jejak stack (sebagai array string) untuk Chrome, Opera, Firefox dan IE10 + modern

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);
}

Pemakaian:

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

Itu mengecualikan dari tumpukan panggilannya sendiri serta judul "Kesalahan" yang digunakan oleh Chrome dan Firefox (tetapi bukan IE).

Seharusnya tidak mogok di browser lama tetapi hanya mengembalikan array kosong. Jika Anda membutuhkan solusi yang lebih universal, lihat stacktrace.js . Daftar browser yang didukungnya benar-benar mengesankan tetapi bagi saya itu sangat besar untuk tugas kecil yang dimaksudkan untuk: 37Kb teks yang diperkecil termasuk semua dependensi.

Konstantin Smolyanin
sumber
7

Pembaruan untuk jawaban Eugene: Objek kesalahan harus dilemparkan agar IE (versi spesifik?) Untuk mengisi stackproperti. Berikut ini harus bekerja lebih baik daripada contohnya saat ini, dan harus menghindari kembali undefinedketika di IE.

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

Catatan 1: Hal semacam ini hanya boleh dilakukan saat debugging, dan dinonaktifkan saat siaran langsung, terutama jika sering dipanggil. Catatan 2: Ini mungkin tidak berfungsi di semua browser, tetapi tampaknya berfungsi di FF dan IE 11, yang sesuai dengan kebutuhan saya.

Patrick Seymour
sumber
6

salah satu cara untuk mendapatkan jejak stack nyata di Firebug adalah dengan membuat kesalahan nyata seperti memanggil fungsi yang tidak terdefinisi:

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);

Atau gunakan console.error()diikuti oleh throwpernyataan karena console.error()menunjukkan jejak stack.

Miller Medeiros
sumber
4

Kode polyfill ini berfungsi di browser modern (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;
}

Jawaban lain:

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

tidak bekerja di IE 11!

Menggunakan arguments.callee.caller - tidak bekerja dalam mode ketat di browser apa pun!

Petr Varyagin
sumber
3

Di Google Chrome (versi 19.0 dan lebih tinggi), cukup melempar pengecualian berfungsi dengan baik. Sebagai contoh:

/* 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();

akan menampilkan jejak stack pada output konsol browser:

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

Semoga bantuan ini.

Rabih Kodeih
sumber
3

fungsi:

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

gunakan case:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
Jaskey
sumber
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>

skrip ini akan menampilkan kesalahan

Amir Buzo
sumber
2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
Denis Orlov
sumber
2
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Donald Duck
1

Agak terlambat ke pesta, tetapi, di sini ada solusi lain, yang secara otomatis mendeteksi jika arguments.callee tersedia, dan menggunakan Kesalahan baru (). Tumpukan jika tidak. Diuji dalam chrome, safari dan firefox.

2 varian - stackFN (n) memberi Anda nama fungsi n dari pemanggil langsung, dan stackArray () memberi Anda sebuah array, stackArray () [0] menjadi pemanggil langsung.

Cobalah di 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();
tidak disinkronkan
sumber
1

Anda dapat menggunakan perpustakaan ini http://www.stacktracejs.com/ . Ini sangat bagus

Dari dokumentasi

Anda juga dapat meneruskan kesalahan Anda sendiri untuk mendapatkan stacktrace tidak tersedia di IE atau 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>
Doua Beri
sumber
Sumber tertaut https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.jsadalah versi lama, versi stabil terbaru (cocok dengan cuplikan-kode) ada di sini:https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.js
Frederic Leitenberger
1

Berikut ini adalah jawaban yang memberi Anda kinerja maksimal (IE 6+) dan kompatibilitas maks. Kompatibel dengan 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>" );
})();

Jack Giffin
sumber
0

Lebih mudah untuk mendapatkan jejak stack di Firefox daripada di IE tetapi pada dasarnya inilah yang ingin Anda lakukan:

Bungkus potongan kode "bermasalah" dalam blok coba / tangkap:

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

Jika Anda akan memeriksa konten objek "kesalahan" itu berisi bidang-bidang berikut:

e.fileName: File sumber / halaman tempat masalah berasal dari e.lineNumber: Nomor baris dalam file / halaman di mana masalah muncul e.message: Pesan sederhana yang menjelaskan jenis kesalahan apa yang terjadi e.name: Jenisnya kesalahan yang terjadi, pada contoh di atas seharusnya 'TypeError' e.stack: Berisi jejak stack yang menyebabkan pengecualian

Saya harap ini membantu Anda.

Michael
sumber
1
Salah. Dia mencoba menangkap pengecualiannya sendiri. Jika dia melempar "asdfg", dia akan mendapatkan objek string, bukan objek pengecualian. Dia tidak mencoba menangkap pengecualian bawaan.
Ivan Vučica
0

Saya harus menyelidiki rekursi yang tak berujung di smartgwt dengan IE11, jadi untuk menyelidiki lebih dalam, saya perlu jejak stack. Masalahnya adalah, saya tidak dapat menggunakan konsol dev, karena reproduksi lebih sulit.
Gunakan yang berikut ini dalam metode javascript:

try{ null.toString(); } catch(e) { alert(e.stack); }
Kirilv
sumber
alert ((Kesalahan baru ()). stack);
Pengingat kaya
0

Wow - Saya tidak melihat satu orang pun dalam 6 tahun yang menyarankan agar kami memeriksa dulu untuk melihat apakah stacktersedia sebelum menggunakannya! Hal terburuk yang dapat Anda lakukan dalam penangan kesalahan adalah melempar kesalahan karena memanggil sesuatu yang tidak ada.

Seperti yang dikatakan orang lain, sementara stacksebagian besar aman untuk digunakan sekarang tidak didukung di IE9 atau sebelumnya.

Saya mencatat kesalahan yang tidak terduga dan jejak tumpukan sangat penting. Untuk dukungan maksimum, pertama saya periksa untuk melihat apakah Error.prototype.stackada dan merupakan fungsi. Jika demikian maka aman untuk digunakan 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)
            {

            }
        };

Sunting: Tampaknya karena stackini adalah properti dan bukan metode, Anda dapat dengan aman menyebutnya bahkan di peramban yang lebih lama. Saya masih bingung karena saya cukup yakin memeriksa Error.prototypebekerja untuk saya sebelumnya dan sekarang tidak - jadi saya tidak yakin apa yang terjadi.

Simon_Weaver
sumber
0

Menggunakan console.error(e.stack)Firefox hanya menunjukkan stacktrace dalam log, Chrome juga menunjukkan pesannya. Ini bisa menjadi kejutan buruk jika pesan itu berisi informasi penting. Selalu login keduanya.

Christophe Roussy
sumber
0

Coba saja

throw new Error('some error here')

Ini berfungsi cukup baik untuk chrome:

masukkan deskripsi gambar di sini

Anthony Zhan
sumber