Node.js'de yığın izlemesi nasıl yazdırılır?


Yanıtlar:


615

Herhangi bir Errornesnenin, stackoluşturulduğu noktayı yakalayan bir üyesi vardır.

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

veya daha basit:

console.trace("Here I am!")

1
veya sadece sys.puts(new Error().stack)(sistem modülünü ekledikten sonra)
sirhc

5
Şu an itibariyle, sys depricated. İle değiştirilir 'util'.
Pindatjuh

12
Ayrıca göstermek için 1 new Error().stackkonsolu dahil etmek istemediğiniz durumlarda çalışır, hangi.
Eugene Beresovsky

1
Bunun bir avantajı trace, mevcut satırı / bağlamı da göstermemesidir stack. Sanırım bu satırı el ile oluşturmak istiyorsanız bilgi hata nesnesinde.
studgeek

130
console.log (err.stack) ve console.trace () size aynı sonuçları vermez. Err.stack size err nesnesinin kendisi için yığın izlemesi verirken (normalde istisnaları hepimizin düşündüğü şekilde çalışır), console.trace () çağrısı yığınını console.trace () çağrıldığı noktada yazdırır. Bu nedenle, daha derin bir kod katmanı tarafından atılan bazı hatalar yakalarsanız, console.trace (), kod artık yığınta olmadığından yığın izlemesinde o daha derin katman kodunu içermez. Ancak console.log (err.stack), bir Error nesnesi attığı sürece daha derin katmanları içerir.
d512

200

Şimdi konsolda bunun için özel bir işlev var:

console.trace()

11
Sadece kulak emin olun yukarıdaki yorumunu hakkında console.trace().
Qix - MONICA

5
Varsayılan olarak bu yalnızca 10 kareyi gösterir, bunu artırmak için komut satırı bağımsız değişkenini kullanabilirsiniz, örneğin--stack_trace_limit=200
Michael

Bir günlük dosyasına çıktı almak isterseniz ne olur?
Ya.

Bu vaatler ve async / bekliyor ile çalışmıyor gibi görünüyor, değil mi?
bluenote10

97

Daha önce yanıtlandığı gibi, trace komutunu kullanabilirsiniz :

console.trace("I am here");

Ancak, bir özel durumun yığın izlemesinin nasıl günlüğe kaydedileceğini araştırmak için bu soruya geldiyseniz , Exception nesnesini günlüğe kaydedebilirsiniz.

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

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

Günlüğe kaydedilecek:

Hata: Beklenmedik bir şey oluştu.
    main'de (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15) Object'te
    . (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    Module._compile adresinde (module.js: 460: 26)
    Object.Module._extensions..js (module.js: 478: 10 ) adresinde )
    Module.load (module.js en: 355: 32)
    310: 12) Function.Module._load (module.js de
    Function.Module.runMain (module.js en: 501: 10)
    devreye alınması (node.js de : 129: 16)
    node.js'de: 814: 3


Node.js sürümünüz 6.0.0'dan küçükse , Exception nesnesinin günlüğe kaydedilmesi yeterli olmaz. Bu durumda, yalnızca yazdırılır:

[Hata: Beklenmedik bir şey oluştu.]

<6 Düğümü sürümünde, geçerli Düğüm sürümünde olduğu gibi hata mesajını ve tüm yığını yazdırmak console.error(e.stack)yerine kullanın console.error(e).


Not: kural dışı durum benzer bir dize olarak oluşturulmuşsa throw "myException", yığın izlemesi ve günlük kaydı e.stackgetirileri tanımlanmamış olarak alınamaz .

Güvende olmak için şunları kullanabilirsiniz:

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

eski ve yeni Node.js sürümlerinde de çalışır.


Olmaz console.error(e)yazdırmak herşeyi içinde edahil nesne e.stack?
drmrbrewer

1
@drmrbrewer, bunu işaret ettiğiniz için teşekkür ederim. Bu davranış 4.x ve 7.x Düğüm sürümleri arasında değişmiş gibi görünüyor (muhtemelen bir V8 değişikliği). Cevabımı güncelledim.
Zanon

1
@drmrbrewer bu davranışın 6.0.0
Zanon

2
üzgünüm çok önemli bir şey keşfettim. İlgili gönderiye yönelik yorumuma bakın: stackoverflow.com/questions/42528677/… . Hatanın kendi kendine günlüğe kaydedilmesi gerçekten de hatanın tüm içeriğini gösterir, ancak diğer metinlerle (dize gibi) birleştirmeye çalışmak yalnızca kısa mesaj bölümünün kullanılmasına neden olur. Bu farkındalıkla her şey çok daha mantıklı.
drmrbrewer

1
günümü kurtaracaksın)
Alex

39

ErrorKonsoldaki yığın izini daha okunabilir bir şekilde yazdırmak için :

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

Örnek sonuç:

[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)' ]


5

Error.captureStackTrace'i (targetObject [, constructorOpt]) deneyin .

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

İşlevi ave bhata yığınında yakalanır ve içinde saklanır myObj.


2
Bir hatanın stackmülke sahip olmasını istiyorsanız , Düğüm> = 6 ise bunu çağırmanız gerekir Error.captureStackTrace(error).
cjbarth

Çağrılan çerçevenin Error.captureStackTraceyığın izlemesinde görünmesini istemiyorsanız, constructorOptarg olarak ileterek çerçeveyi atlayabileceğinizi unutmayın .
Ullauri

3

Bildiğim kadarıyla nodejs'de tam yığın izlemesi yazdırmak mümkün değil, sadece bir "kısmi" yığın izlemesi yazdırabilirsiniz, kodda nereden geldiğinizi göremezsiniz, sadece İstisna oluşur. Ryan Dahl, bu youtube videosunda açıklıyor. Kesin olduğu için 56: 30'da http://youtu.be/jo_B4LTHi3I . Bu yardımcı olur umarım


2
doğru, ancak @ Timboudreau'nun cevabındaki modül bunu düzeltiyor "
Bogdan D

3

@isaacs yanıtı doğrudur, ancak daha spesifik veya daha temiz bir hata yığınına ihtiyacınız varsa, bu işlevi kullanabilirsiniz:

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

   return err.stack;
}

Bu işlev doğrudan ilham console.traceişlev NodeJS .

Kaynak kodu: Son sürüm veya Eski sürüm .


1
işe yaramaz, yalnızca geçerli satırdaki yığını gösterir (bu hatanın oluştuğu satırı göstermez). err.stackdaha doğru cevaptır.
Ian Zhong

2

Yalnızca hatanın yığın izlemesini (hata iletisini değil) günlüğe kaydetmek istiyorsanız, Düğüm 6 ve üstü, yığın izinin içindeki hata adını ve iletisini otomatik olarak içerir;

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

Bu geçici çözüm yalnızca hata adını ve yığın izlemesini günlüğe kaydeder (böylece hata iletisini biçimlendirebilir ve kodunuzda başka bir yerde istediğiniz gibi görüntüleyebilirsiniz).

Yukarıdaki örnek, yalnızca yığın izlemesinin izlediği hata adını yazdırır, örneğin:

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)

Onun yerine:

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)

1

Birinin hala benim gibi araması durumunda, o zaman "yığın izleme" olarak adlandırdığımız bir modül var. Gerçekten popüler. NPM Bağlantısı

Sonra iz boyunca yürüyün.

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

Veya sadece izi yazdırın:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.