Làm cách nào để in dấu vết ngăn xếp trong Node.js?


Câu trả lời:


615

Bất kỳ Errorđối tượng nào cũng có một stackthành viên bẫy điểm mà nó được xây dựng.

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

hoặc đơn giản hơn:

console.trace("Here I am!")

1
hoặc chỉ sys.puts(new Error().stack)(sau khi thêm mô-đun hệ thống)
sirhc

5
Đến bây giờ, sys bị lỗi thời. Nó được thay thế bởi 'util'.
Pindatjuh

12
+1 cũng hiển thị new Error().stack, hoạt động trong trường hợp bạn không muốn liên quan đến bảng điều khiển.
Eugene Beresovsky

1
Một lợi thế của tracenó là hiển thị dòng / bối cảnh hiện tại cũng stackkhông. Thông tin nằm trong đối tượng lỗi nếu bạn muốn tự tạo dòng đó.
studgeek

130
console.log (err.stack) và console.trace () không cho bạn kết quả tương tự. Trong khi err.stack cung cấp cho bạn dấu vết ngăn xếp cho chính đối tượng err (hoạt động theo cách mà tất cả chúng ta thường nghĩ về ngoại lệ), console.trace () sẽ in ra ngăn xếp cuộc gọi tại điểm mà console.trace () đang được gọi. Vì vậy, nếu bạn bắt gặp một số lỗi bị ném bởi một lớp mã sâu hơn, console.trace () sẽ không chứa mã lớp sâu hơn đó trong theo dõi ngăn xếp vì mã đó không còn trên ngăn xếp. Tuy nhiên, console.log (err.stack) sẽ chứa các lớp sâu hơn miễn là nó ném một đối tượng Error.
d512

200

Bây giờ có một chức năng chuyên dụng trên bàn điều khiển cho điều đó:

console.trace()

11
Chỉ cần chắc chắn để lưu ý các ý kiến trên về console.trace().
Qix - MONICA ĐƯỢC PHÂN PHỐI

5
Theo mặc định, điều này sẽ chỉ hiển thị 10 khung, bạn có thể sử dụng đối số dòng lệnh để tăng điều này, ví dụ:--stack_trace_limit=200
Michael

Điều gì nếu bạn muốn xuất ra một tệp nhật ký?
Ya.

Điều đó dường như không hoạt động với những lời hứa và không đồng bộ / chờ đợi, phải không?
bluenote10

97

Như đã trả lời, bạn chỉ cần sử dụng lệnh theo dõi :

console.trace("I am here");

Tuy nhiên, nếu bạn đến câu hỏi này để tìm cách ghi nhật ký theo dõi ngăn xếp của một ngoại lệ , bạn chỉ cần đăng nhập đối tượng Ngoại lệ.

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

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

Nó sẽ đăng nhập:

Lỗi: Một cái gì đó bất ngờ đã xảy ra.
    tại chính (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    tại Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    tại Module._compile (module.js: 460: 26)
    tại Object.Module._extensions..js (module.js: 478: 10 )
    tại Module.load (module.js: 355: 32)
    tại Function.Module._load (module.js: 310: 12)
    tại Function.Module.runMain (module.js: 501: 10)
    khi khởi động (node.js : 129: 16)
    tại node.js: 814: 3


Nếu phiên bản Node.js của bạn là <hơn 6.0.0 , việc ghi nhật ký đối tượng Ngoại lệ sẽ không đủ. Trong trường hợp này, nó sẽ chỉ in:

[Lỗi: Đã xảy ra sự cố không mong muốn.]

Đối với phiên bản Nút <6, sử dụng console.error(e.stack)thay vì console.error(e)in thông báo lỗi cộng với ngăn xếp đầy đủ, giống như phiên bản Nút hiện tại.


Lưu ý: nếu ngoại lệ được tạo dưới dạng một chuỗi như thế throw "myException", thì không thể truy xuất dấu vết ngăn xếp và ghi e.stacklại sản lượng không xác định .

Để an toàn, bạn có thể sử dụng

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

và nó sẽ hoạt động cho các phiên bản Node.js cũ và mới.


Không console.error(e)in mọi thứ trong eđối tượng, bao gồm e.stack?
drmrbrewer

1
@drmrbrewer, cảm ơn bạn đã chỉ ra điều này. Có vẻ như hành vi đã thay đổi giữa các phiên bản Node 4.x và 7.x (có thể là thay đổi V8). Tôi đã cập nhật câu trả lời của mình.
Zanon

1
@drmrbrewer xác nhận rằng hành vi này đã thay đổi trên phiên bản 6.0.0
Zanon

2
xin lỗi tôi chỉ phát hiện ra một cái gì đó quan trọng Xem bình luận của tôi đối với bài đăng liên quan: stackoverflow.com/questions/42528677/ . Có vẻ như việc tự mình ghi lại lỗi thực sự hiển thị toàn bộ nội dung của lỗi, nhưng cố gắng nối nó (như một chuỗi) với văn bản khác sẽ chỉ sử dụng phần thông báo ngắn gọn. Tất cả có ý nghĩa hơn rất nhiều với nhận thức đó.
drmrbrewer

1
bạn tiết kiệm trong ngày của tôi)
Alex

39

Để in stacktrace của Errortrong bảng điều khiển theo cách dễ đọc hơn:

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

Kết quả ví dụ:

[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

Hãy thử Error.captureStackTrace (targetObject [, constructorOpt]) .

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

Các chức năng abđược nắm bắt trong ngăn xếp lỗi và được lưu trữ trong myObj.


2
Nếu bạn muốn có lỗi để có một thuộc stacktính, bạn sẽ cần gọi đây nếu Node> = 6 : Error.captureStackTrace(error).
cjbarth

Lưu ý rằng nếu bạn không muốn khung hình được gọi Error.captureStackTracehiển thị trong theo dõi ngăn xếp, bạn có thể bỏ qua nó bằng cách chuyển nó dưới dạng đối số constructorOpt.
Ullauri

3

Đối với những gì tôi biết, việc in dấu vết ngăn xếp hoàn chỉnh trong nodejs là không thể, bạn chỉ có thể in dấu vết ngăn xếp "một phần", bạn không thể thấy nơi bạn đến từ mã, nơi xảy ra Ngoại lệ. Đó là những gì Ryan Dahl giải thích trong video youtube này. http://youtu.be/jo_B4LTHi3I vào tối thiểu 56:30 vì chính xác. Hi vọng điêu nay co ich


2
đúng, nhưng mô-đun trong câu trả lời "sửa lỗi" của @ Timboudreau rằng
Bogdan D

3

Câu trả lời @isaacs là chính xác, nhưng nếu bạn cần ngăn xếp lỗi cụ thể hơn hoặc rõ ràng hơn , bạn có thể sử dụng chức năng này:

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

   return err.stack;
}

Hàm này được lấy cảm hứng trực tiếp từ console.tracehàm trong NodeJS .

Mã nguồn: Phiên bản gần đây hoặc Phiên bản cũ .


1
nó không hoạt động, chỉ hiển thị ngăn xếp từ dòng hiện tại (không phải dòng này xảy ra lỗi). err.stacklà câu trả lời đúng hơn.
Ian Zhong

2

Nếu bạn muốn chỉ ghi nhật ký theo dõi ngăn xếp của lỗi (chứ không phải thông báo lỗi) Nút 6 trở lên sẽ tự động bao gồm tên lỗi và thông báo bên trong theo dõi ngăn xếp, điều này hơi khó chịu nếu bạn muốn thực hiện một số xử lý lỗi tùy chỉnh:

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

Cách giải quyết này sẽ chỉ ghi lại tên lỗi và theo dõi ngăn xếp (ví dụ, bạn có thể định dạng thông báo lỗi và hiển thị nó theo cách bạn muốn ở một nơi khác trong mã của mình).

Ví dụ trên sẽ chỉ in tên lỗi theo dấu vết ngăn xếp, ví dụ:

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)

Thay vì:

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

Trong trường hợp ai đó vẫn đang tìm kiếm cái này giống như tôi, thì có một mô-đun chúng ta có thể sử dụng gọi là "stack-vết". Nó thực sự phổ biến. Liên kết NPM

Sau đó đi bộ qua dấu vết.

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

Hoặc chỉ đơn giản là in dấu vết:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.