Bagaimana cara mencetak jejak stack di Node.js?

Jawaban:

615

Setiap Errorobjek memiliki stackanggota yang menjebak titik di mana ia dibangun.

var stack = new Error().stack
console.log( stack )

atau lebih sederhana:

console.trace("Here I am!")
isaacs
sumber
1
atau hanya sys.puts(new Error().stack)(setelah menambahkan modul sistem)
sirhc
5
Sampai sekarang, sys sudah dirampas. Digantikan oleh 'util'.
Pindatjuh
12
+1 untuk juga ditampilkan new Error().stack, yang berfungsi jika Anda tidak ingin melibatkan konsol.
Eugene Beresovsky
1
Salah satu kelebihannya traceadalah ia menunjukkan garis / konteks saat ini juga yang stacktidak. Info ada di objek kesalahan jika Anda ingin secara manual membuat garis itu, saya kira.
studgeek
130
console.log (err.stack) dan console.trace () tidak memberi Anda hasil yang sama. Sedangkan err.stack memberi Anda jejak stack untuk objek err itu sendiri (berfungsi dengan cara yang biasanya kita pikirkan tentang pengecualian), console.trace () akan mencetak tumpukan panggilan pada titik di mana console.trace () dipanggil. Jadi, jika Anda menemukan beberapa kesalahan yang dilemparkan oleh lapisan kode yang lebih dalam, console.trace () tidak akan berisi kode lapisan yang lebih dalam di jejak tumpukan karena kode itu tidak lagi berada di tumpukan. Namun, console.log (err.stack) akan berisi lapisan yang lebih dalam selama ia melemparkan objek Error.
d512
200

Sekarang ada fungsi khusus pada konsol untuk itu:

console.trace()
Mariusz Nowak
sumber
11
Hanya pastikan untuk memperhatikan komentar di atas tentang console.trace().
Qix - MONICA DISALAHKAN
5
Secara default ini hanya akan menampilkan 10 frame, Anda dapat menggunakan argumen baris perintah untuk menambah ini, misalnya--stack_trace_limit=200
Michael
Bagaimana jika Anda ingin menghasilkan file log?
Ya
Tampaknya itu tidak bekerja dengan janji dan tidak menunggu, kan?
bluenote10
97

Seperti yang sudah dijawab, Anda cukup menggunakan perintah jejak :

console.trace("I am here");

Namun, jika Anda sampai pada pertanyaan ini dengan mencari tentang cara mencatat jejak stack pengecualian , Anda bisa mencatat objek Pengecualian.

try {  
  // if something unexpected
  throw new Error("Something unexpected has occurred.");     

} catch (e) {
  console.error(e);
}

Itu akan masuk:

Kesalahan: Sesuatu yang tidak terduga telah terjadi.
    at main (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9:15)
    di Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    di Module._compile (module.js: 460: 26)
    di Object.Module._extensions..js (module.js: 478: 10 )
    di Module.load (module.js: 355: 32)
    di Function.Module._load (module.js: 310: 12)
    di Function.Module.runMain (module.js: 501: 10)
    saat startup (node.js : 129: 16)
    di node.js: 814: 3


Jika versi Node.js Anda <dari 6.0.0 , logging objek Pengecualian tidak akan cukup. Dalam hal ini, hanya akan mencetak:

[Kesalahan: Sesuatu yang tidak terduga telah terjadi.]

Untuk versi Node <6, gunakan console.error(e.stack)sebagai ganti console.error(e)untuk mencetak pesan kesalahan plus tumpukan penuh, seperti versi Node saat ini.


Catatan: jika pengecualian dibuat sebagai string seperti throw "myException", itu tidak mungkin untuk mengambil jejak tumpukan dan mencatat e.stackhasil tidak terdefinisi .

Agar aman, Anda bisa menggunakan

console.error(e.stack || e);

dan itu akan bekerja untuk versi Node.js lama dan baru.

Zanon
sumber
Tidak akan console.error(e)mencetak semua yang ada di eobjek, termasuk e.stack?
drmrbrewer
1
@drmrbrewer, terima kasih telah menunjukkan ini. Tampaknya perilaku telah berubah antara Node versi 4.x dan 7.x (mungkin perubahan V8). Saya telah memperbarui jawaban saya.
Zanon
1
@drmrbrewer mengonfirmasi bahwa perilaku ini berubah pada versi 6.0.0
Zanon
2
maaf saya baru menemukan sesuatu yang penting. Lihat komentar saya terhadap posting terkait: stackoverflow.com/questions/42528677/… . Tampaknya mencatat kesalahan sendiri memang menunjukkan seluruh konten kesalahan, tetapi mencoba menyatukannya (seperti string) dengan teks lain akan menyebabkan hanya bagian pesan singkat yang digunakan. Semua itu jauh lebih masuk akal dengan realisasi itu.
drmrbrewer
1
Anda menghemat hari saya)
Alex
39

Untuk mencetak stacktrace Errordi konsol dengan cara yang lebih mudah dibaca:

console.log(ex, ex.stack.split("\n"));

Contoh hasil:

[Error] [ 'Error',
  '    at repl:1:7',
  '    at REPLServer.self.eval (repl.js:110:21)',
  '    at Interface.<anonymous> (repl.js:239:12)',
  '    at Interface.EventEmitter.emit (events.js:95:17)',
  '    at Interface._onLine (readline.js:202:10)',
  '    at Interface._line (readline.js:531:8)',
  '    at Interface._ttyWrite (readline.js:760:14)',
  '    at ReadStream.onkeypress (readline.js:99:10)',
  '    at ReadStream.EventEmitter.emit (events.js:98:17)',
  '    at emitKey (readline.js:1095:12)' ]
ruX
sumber
5

Coba Error.captureStackTrace (targetObject [, constructorOpt]) .

const myObj = {};
function c() {
  // pass
}

function b() {
    Error.captureStackTrace(myObj)
    c()
} 

function a() {
    b()
}

a()

console.log(myObj.stack)

Fungsi adan bditangkap dalam tumpukan kesalahan dan disimpan di myObj.

Zheeeng
sumber
2
Jika Anda ingin kesalahan untuk memiliki stackproperti, Anda harus memanggil ini jika Node> = 6: Error.captureStackTrace(error).
cjbarth
Perhatikan bahwa jika Anda tidak ingin bingkai yang dipanggil Error.captureStackTracemuncul di jejak tumpukan, Anda dapat menghilangkannya dengan meneruskannya sebagai constructorOptargumen.
Ullauri
3

Untuk yang saya tahu mencetak jejak stack lengkap dalam nodejs tidak mungkin, Anda hanya dapat mencetak jejak stack "parsial", Anda tidak bisa melihat dari mana Anda berasal dari kode, hanya di mana Pengecualian terjadi. Itulah yang dijelaskan Ryan Dahl dalam video youtube ini. http://youtu.be/jo_B4LTHi3I pukul min 56:30 karena tepat. Semoga ini membantu

ElHacker
sumber
2
benar, tetapi modul di @ Timboudreau menjawab "perbaikan" itu
Bogdan D
3

Jawaban @isaacs benar, tetapi jika Anda memerlukan tumpukan kesalahan yang lebih spesifik atau lebih bersih , Anda dapat menggunakan fungsi ini:

function getCleanerStack() {
   var err = new Error();
   Error.captureStackTrace(err, getStack);

   return err.stack;
}

Fungsi ini terinspirasi langsung dari console.tracefungsi di NodeJS .

Kode sumber: Versi terbaru atau versi lama .

Tentakel Squidward
sumber
1
tidak berfungsi, hanya tampilkan tumpukan dari baris saat ini (bukan baris kesalahan ini terjadi). err.stackadalah jawaban yang lebih benar.
Ian Zhong
2

Jika Anda hanya ingin mencatat jejak tumpukan kesalahan (dan bukan pesan kesalahan) Node 6 dan di atas secara otomatis menyertakan nama kesalahan dan pesan di dalam jejak tumpukan, yang sedikit mengganggu jika Anda ingin melakukan beberapa penanganan kesalahan khusus:

console.log(error.stack.replace(error.message, ''))

Pemecahan masalah ini hanya akan mencatat nama kesalahan dan jejak tumpukan (jadi Anda dapat, misalnya, memformat pesan kesalahan dan menampilkannya seperti yang Anda inginkan di tempat lain dalam kode Anda).

Contoh di atas hanya akan mencetak nama kesalahan diikuti oleh jejak tumpukan, misalnya:

Error: 
    at /Users/cfisher/Git/squashed/execProcess.js:6:17
    at ChildProcess.exithandler (child_process.js:213:5)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
    at Socket.<anonymous> (internal/child_process.js:334:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:498:12)

Dari pada:

Error: Error: Command failed: sh ./commands/getBranchCommitCount.sh HEAD
git: 'rev-lists' is not a git command. See 'git --help'.

Did you mean this?
        rev-list

    at /Users/cfisher/Git/squashed/execProcess.js:6:17
    at ChildProcess.exithandler (child_process.js:213:5)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
    at Socket.<anonymous> (internal/child_process.js:334:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:498:12)
GrayedFox
sumber
1

Jika seseorang masih mencari ini seperti saya, maka ada modul yang bisa kita gunakan disebut "stack-trace". Ini sangat populer. Tautan NPM

Lalu berjalanlah melewati jejak.

  var stackTrace = require('stack-trace');
  .
  .
  .
  var trace = stackTrace.get();
  trace.map(function (item){ 
    console.log(new Date().toUTCString() + ' : ' +  item.toString() );  
  });

Atau cukup cetak jejak:

var stackTrace = require('stack-trace');
.
.
.
var trace = stackTrace.get();
trace.toString();
Laszlo
sumber
0

Anda dapat menggunakan modul node-stack-trace yang merupakan modul penuh daya untuk melacak tumpukan panggilan.

Nitin9791
sumber