Як надрукувати слід стека в Node.js?


Відповіді:


615

Будь-який Errorоб’єкт має stackчлен, який захоплює точку, в якій він був побудований.

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

або простіше:

console.trace("Here I am!")

1
або просто sys.puts(new Error().stack)(після додавання системного модуля)
sirhc

5
Станом на теперішній час систематизовано втратили силу. Його замінюють на 'util'.
Піндатюх

12
+1 також показує new Error().stack, що працює у випадках, коли ви не хочете залучати консоль.
Євген Бересовський

1
Однією з переваг traceє те, що він показує поточний рядок / контекст, а також stackцього не робить. Інформація знаходиться в об’єкті помилки, якщо ви хочете вручну створити цей рядок, я думаю.
studgeek

130
console.log (err.stack) і console.trace () не дають однакових результатів. Тоді як err.stack дає вам стеження за стеком самого об’єкта помилки (функціонує так, як ми зазвичай думаємо про винятки), console.trace () роздрукує стек викликів у точці, куди викликається console.trace (). Отже, якщо ви виявите помилку, яку кидає якийсь більш глибокий шар коду, console.trace () не буде містити цей код більш глибокого шару у сліді стека, оскільки цей код більше не знаходиться у стеку. Однак console.log (err.stack) буде містити більш глибокі шари до тих пір, поки він кине об'єкт Error.
d512

200

Тепер для консолі призначена спеціальна функція :

console.trace()

11
Просто переконайтеся , що прислухатися вищезгаданий коментар про console.trace().
Qix - МОНІКА ПОМИЛИЛА

5
За замовчуванням це покаже лише 10 кадрів, ви можете використовувати аргумент командного рядка, щоб збільшити це, наприклад--stack_trace_limit=200
Michael

Що робити, якщо ви хочете вивести файл журналу?
Я.

Схоже, це не працює з обіцянками та асинхронізує / чекає, чи не так?
bluenote10

97

Як уже відповіли, ви можете просто скористатися командою trace :

console.trace("I am here");

Однак якщо ви звернулися до цього питання, шукаючи про те, як записати слід стека виключення , ви можете просто ввідати об'єкт Exception.

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

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

Він увійде:

Помилка: сталося щось несподіване.
    в основному (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    в Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    в Module._compile (module.js: 460: 26)
    в Object.Module._extensions..js (module.js: 478: 10 )
    на Module.load (module.js: 355: 32)
    у Function.Module._load (module.js: 310: 12)
    на Function.Module.runMain (module.js: 501: 10)
    при запуску (node.js : 129: 16)
    на node.js: 814: 3


Якщо ваша версія Node.js <6.0.0 , реєстрація об'єкта «Виняток» буде недостатньою. У цьому випадку він буде друкувати лише:

[Помилка: сталося щось несподіване.]

Для версії Node <6 використовуйте console.error(e.stack)замість того, console.error(e)щоб надрукувати повідомлення про помилку плюс повний стек, як це робить поточна версія вузла.


Примітка: якщо виняток створено у вигляді рядка throw "myException", неможливо отримати слід стека та e.stackдоходи журналу не визначені .

Щоб бути безпечним, ви можете використовувати

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

і він буде працювати для старих і нових версій Node.js.


Не console.error(e)вдасться роздрукувати все в eоб’єкті, в тому числі e.stack?
drmrbrewer

1
@drmrbrewer, дякую, що вказали на це. Здається, поведінка змінилася між версіями Node 4.x та 7.x (можливо, зміна V8). Я оновив свою відповідь.
Занон

1
@drmrbrewer підтвердив, що така поведінка змінилася у версії 6.0.0
Занон

2
вибачте, що я просто виявив щось вирішальне. Дивіться мій коментар до пов’язаного допису: stackoverflow.com/questions/42528677/… . Здається, що реєстрація помилки самостійно відображає весь вміст помилки, але спроба об'єднати її (як рядок) з іншим текстом призведе до використання лише частини короткого повідомлення. Це все має набагато більше сенсу з цією реалізацією.
drmrbrewer

1
ви врятуєте мій день)
Алекс

39

Щоб друкувати стек-трек Errorконсолі більш читаним способом:

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

Приклад результату:

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

9

Завдяки доступному модулю Node можна отримати сліди стека в повному розмірі з Node (хоча і з незначним покаранням продуктивності): http://www.mattinsler.com/post/26396305882/announcing-longjohn-long-stack -traces-for-node-js


4
Посилання мертве, але можна прочитати тут заархівовану копію або перевірити бібліотеку .
Кодифікація

5

Спробуйте Error.captureStackTrace (targetObject [, constructorOpt]) .

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

Функція aі bфіксується в стеці помилок і зберігається в myObj.


2
Якщо ви хочете про помилку мати stackвластивість, вам потрібно викликати це , якщо вузол> = 6: Error.captureStackTrace(error).
cjbarth

Зауважте, що якщо ви не хочете, щоб кадр, який викликав, Error.captureStackTraceвідображався у сліді стека, його можна опустити, передавши його як constructorOptаргумент.
Уллаурі

3

Оскільки я знаю, друк повного сліду стека в nodejs неможливий, ви можете просто надрукувати "частковий" слід стека, ви не можете бачити, звідки ви прийшли в коді, саме там, де відбувається виняток. Саме це пояснює Райан Дал у цьому відео на YouTube. http://youtu.be/jo_B4LTHi3I о хв. 56:30 за точність. Сподіваюсь, це допомагає


2
правда, але модуль у відповіді @ Timboudreau "виправляє", що
Богдан Д

3

Відповідь @isaacs правильна, але якщо вам потрібен більш конкретний чи чистіший стек помилок , ви можете скористатися цією функцією:

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

   return err.stack;
}

Ця функція натхненна безпосередньо console.traceфункцією в NodeJS .

Вихідний код: Остання версія або стара версія .


1
він не працює, показуйте лише стек з поточного рядка (не той рядок, який сталася ця помилка). err.stackправильніша відповідь.
Ян Чжун

2

Якщо ви хочете лише зафіксувати трасування стека помилки (а не повідомлення про помилку). Вузол 6 і вище автоматично включає ім’я та повідомлення про помилку всередині сліду стека, що трохи дратує, якщо ви хочете виконати якусь власну обробку помилок:

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

У цьому вирішенні буде записано лише ім'я помилки та трасування стека (так що ви можете, наприклад, відформатувати повідомлення про помилку та відобразити його як потрібно десь у коді).

Наведений вище приклад видав би лише ім'я помилки, за яким слідує стежка стека, наприклад:

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)

Замість:

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

Якщо хтось все ще шукає такого, як я, то є модуль, який ми можемо використовувати під назвою "стек-слід". Це дійсно популярно. NPM Link

Потім пройдіться слідом.

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

Або просто надрукуйте слід:

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

0

ви можете використовувати node-stack-trace module, який є повноцінним модулем для відстеження стеків викликів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.