Как распечатать трассировку стека в Node.js?


383

Кто-нибудь знает, как печатать трассировку стека в Node.js?

469

Любой объект Error имеет объект stack, который захватывает точку, в которой он был построен.

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

или более просто:

console.trace("Here I am!") 
+1

или просто 'sys.puts (новый Error(). Stack)' (после добавления системного модуля) 09 авг. 102010-08-09 04:48:52

+4

На данный момент sys лишен. Он заменяется на '' util''. 14 апр. 112011-04-14 18:15:25

+10

+1 для также отображается 'new Error(). Stack', который работает в тех случаях, когда вы не хотите включать консоль. 31 июл. 122012-07-31 04:19:03

+1

Одним из преимуществ '' 'trace''' является отображение текущей строки/контекста, в которой' '' stack''' нет. Информация находится в объекте ошибки, если вы хотите вручную создать эту строку, я думаю. 30 авг. 122012-08-30 16:54:27

+99

console.log (err.stack) и console.trace() не дают вам одинаковых результатов. В то время как err.stack дает вам трассировку стека для самого объекта err (функционирует так, как мы все обычно думаем об исключениях), console.trace() выдает стек вызовов в точке, где вызывается console.trace(). Поэтому, если вы заметите ошибку, вызванную некоторым более глубоким слоем кода, console.trace() не будет содержать этот более глубокий код слоя в трассировке стека, поскольку этот код больше не находится в стеке. Однако console.log (err.stack) будет содержать более глубокие слои, пока он бросает объект Error. 21 фев. 132013-02-21 18:10:47


162

Теперь есть dedicated function on console для этого:

console.trace() 
+9

Просто не забудьте прислушаться [приведенный выше комментарий] (http://stackoverflow.com/questions/2923858/how-to-print-a-stack-trace-in-nodejs#comment21085596_2932410) о 'console.trace()' , 13 сен. 142014-09-13 23:09:02

+4

По умолчанию это отображает только 10 кадров, вы можете использовать аргумент командной строки, чтобы увеличить это, например. '--stack_trace_limit = 200' 15 май. 162016-05-15 07:15:37


3

За то, что я знаю, что печать полный трассировки стека в nodejs не представляется возможным, вы можете просто напечатайте «частичную» трассировку стека, вы не можете видеть, откуда вы пришли в коде, где происходит исключение. Вот что Райан Дал объясняет в этом видео на YouTube. http://youtu.be/jo_B4LTHi3I на min 56:30 для точного. Надеюсь, что это помогает

+1

true, но модуль в ответе @ Timboudreau «исправляет», что 19 дек. 142014-12-19 15:14:49


7

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

  0

Ссылка мертва, но можно просмотреть [архивированную копию здесь] (https://web.archive.org/web/20160309113159/http : //www.mattinsler.com/post/26396305882/announcing-longjohn-long-stack-traces-for-nodejs) или проверьте [библиотеку] (https://github.com/mattinsler/longjohn). 25 янв. 182018-01-25 01:11:45


31

Для печати StackTrace из 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)' ] 

57

Как уже ответили, вы можете просто использовать trace команда:

console.trace("I am here"); 

Однако , если вы пришли на этот вопрос в поисках о том, как войти в трассировку стека исключения, вы можете просто войти в объект Exception.

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

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

Он зарегистрирует:

Error: Something unexpected has occurred.
    at main (c:\Users\Me\Documents\MyApp\app.js:9:15)
    at Object. (c:\Users\Me\Documents\MyApp\app.js:17:1)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3


Если ваша версия Node.js является < чем 6.0.0, регистрация объекта Exception не будет достаточно. В этом случае он будет печатать только:

[Error: Something unexpected has occurred.]

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


Примечание: если исключение создается в виде строки, как throw "myException", это не возможно, чтобы получить трассировку стека и протоколирование e.stack дает неопределенную.

Чтобы быть в безопасности, вы можете использовать

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

и он будет работать на старых и новых Node.js версий.

  0

Не будет 'console.error (e)' print * everything * в объекте 'e', включая' e.stack'? 01 мар. 172017-03-01 09:02:09

+1

@drmrbrewer, спасибо, что указали это. Похоже, что поведение изменилось между версиями Node 4.x и 7.x (возможно, с изменением V8). Я обновил свой ответ. 01 мар. 172017-03-01 16:57:23

+1

@drmrbrewer подтвердил, что это поведение изменилось в версии 6.0.0 01 мар. 172017-03-01 17:25:06

  0

У вас есть ссылка на это кажущееся изменение в поведении? Я все еще вижу (с узлом '6.9.4'), что' console.error (e) 'только печатает краткое сообщение. И я подозреваю, что это потому, что он печатает представление 'toString'' e', а 'toString' для' e' возвращает только сообщение и ничего больше: https://developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/Global_Objects/Ошибка/toString 02 мар. 172017-03-02 14:40:01

  0

@ drmrbrewer попробуйте установить ** [n] (https: // github.com/tj/n) **, чтобы протестировать различные версии узлов на вашем компьютере или просмотреть [этот тест с узлом 7.4] (https://repl.it/GE5e/1) и сравнить его с [узлом 0.8] (http://www.node-console.com/script/code). Я не мог получить постоянную ссылку для последней, но запустил 'console.error (новая ошибка (« test »))', чтобы увидеть разницу. Что касается ссылки об этом изменении поведения, я не смог получить его в журналах с изменениями в Node. Кажется, это изменение V8, но я также не смог подтвердить. 02 мар. 172017-03-02 15:47:55

+1

жаль, что я только что обнаружил что-то важное. См. Мой комментарий к соответствующему сообщению: http://stackoverflow.com/questions/42528677/how-to-console-log-an-error-in-node-js/42538065#comment72263214_42532877. Кажется, что сама запись ошибки сама по себе показывает весь контент ошибки, но попытка ее конкатенации (например, строки) с другим текстом приведет к использованию только части краткого сообщения. Все это имеет смысл с этой реализацией. 02 мар. 172017-03-02 19:52:46


0

Вы можете использовать модуль node-stack-trace, который является полнофункциональным модулем для отслеживания вызовов.


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) 

0

Попробуйте 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.