จะรับผลลัพธ์ของ console.trace () เป็น string ใน javascript ด้วย chrome หรือ firefox ได้อย่างไร


100

console.trace()แสดงผลลัพธ์บนคอนโซล
ฉันต้องการได้ผลลัพธ์เป็นสตริงและบันทึกลงในไฟล์ ฉันไม่ได้กำหนดชื่อฟังก์ชั่นและฉันยังไม่สามารถได้รับชื่อของพวกเขาด้วย

callee.caller.name


1
สิ่งนี้ใช้ไม่ได้ใน PhantomJS :(
ekkis

คำตอบ:


104

ผมไม่แน่ใจว่าเกี่ยวกับ Firefox แต่ใน v8 / captureStackTraceโครเมี่ยมคุณสามารถใช้วิธีในตัวสร้างข้อผิดพลาดที่เรียกว่า ( ข้อมูลเพิ่มเติมที่นี่ )

ดังนั้นวิธีที่แฮ็กจะได้รับคือ:

var getStackTrace = function() {
  var obj = {};
  Error.captureStackTrace(obj, getStackTrace);
  return obj.stack;
};

console.log(getStackTrace());

โดยปกติgetStackTraceจะอยู่ในสแต็กเมื่อถูกจับภาพ อาร์กิวเมนต์ที่สองไม่รวมgetStackTraceจากการรวมอยู่ในการติดตามสแต็ก


18
ขอบคุณสำหรับข้อมูล. ที่ทำงานใน chrome แต่ไม่ได้ใน firefox Error().stackดังนั้นฉันค้นหาอีกครั้งและพบว่า แม้ว่าชื่ออ็อบเจ็กต์และฟังก์ชันจะหายไปใน firefox และชื่ออ็อบเจ็กต์จะหายไปใน chrome (เช่นเดียวกับError.captureStackTrace) ใช้Error().stackงานได้ทั้งเบราว์เซอร์และให้ข้อมูลเพียงพอในการดีบัก
js_

ผลลัพธ์เดียวกันกับคำตอบของ @Konstantin Smolyanin รายละเอียดที่ จำกัด เช่นเดียวกับผลลัพธ์
Codebeat

นี่ไม่ควรเป็นคำตอบที่ยอมรับได้ สแต็กที่คุณได้รับที่นี่คือ "ตัดลง" ที่มีเฉพาะ "ส่วนบนสุด" ในขณะที่ console.trace () จะแสดงสแต็กแบบเต็ม ดูตัวอย่างความลึกของสแตก 30 ได้ที่นี่: stackoverflow.com/questions/62768598/…
mathheadinclouds

35

Error.stack คือสิ่งที่คุณต้องการ ใช้งานได้ใน Chrome และ Firefox ตัวอย่างเช่น

try { var a = {}; a.debug(); } catch(ex) {console.log(ex.stack)}

จะให้ใน Chrome:

TypeError: Object #<Object> has no method 'debug'
    at eval at <anonymous> (unknown source)
    at eval (native)
    at Object._evaluateOn (unknown source)
    at Object._evaluateAndWrap (unknown source)
    at Object.evaluate (unknown source)

และใน Firefox:

@http://www.google.com.ua/:87 _firebugInjectedEvaluate("with(_FirebugCommandLine){try { var a = {}; a.debug() } catch(ex) {console.log(ex.stack)}\n};")
@http://www.google.com.ua/:87 _firebugEvalEvent([object Event])
@http://www.google.com.ua/:67

2
ขอบคุณสำหรับคำตอบ. แต่จะใช้ได้เฉพาะเมื่อมีข้อยกเว้นเกิดขึ้น ฉันต้องการรับสแต็กแทร็กโดยไม่มีข้อยกเว้น
js_

10
What about(new Error).stack
JasonSmith

สิ่งนี้ควรทำให้เกิดข้อยกเว้นใน a.debug () - เป็นวิธีที่มีราคาแพงในการรับสแต็ก แต่ควรใช้งานได้
fijiaaron

วิธีนี้ยังมีประโยชน์เมื่อพยายามดึงร่องรอยจากโค้ดบางตัวที่รันได้เท่านั้นเช่น PhantomJS หรือสิ่งที่คล้ายกันไม่ว่าด้วยเหตุผลใดก็ตาม
waxspin

20

สิ่งนี้จะให้การติดตามสแต็ก (เป็นอาร์เรย์ของสตริง) สำหรับ Chrome, Firefox, Opera และ IE10 + ที่ทันสมัย

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

การใช้งาน:

console.log(getStackTrace().join('\n'));

โดยไม่รวมการเรียกของตัวเองรวมทั้งชื่อ "ข้อผิดพลาด" ที่ Chrome และ Firefox ใช้ (แต่ไม่ใช่ IE)

ไม่ควรขัดข้องกับเบราว์เซอร์รุ่นเก่า แต่เพียงส่งคืนอาร์เรย์ว่าง หากคุณต้องการดูการแก้ปัญหาสากลมากขึ้นในstacktrace.js รายการเบราว์เซอร์ที่รองรับนั้นน่าประทับใจมาก แต่ในความคิดของฉันมันใหญ่มากสำหรับงานเล็ก ๆ ที่มีไว้สำหรับ: ข้อความย่อขนาด 37Kb รวมถึงการอ้างอิงทั้งหมด


12

มีไลบรารีที่เรียกว่าstacktrace.jsที่ให้คุณข้ามสแต็กเทรซของเบราว์เซอร์ คุณสามารถใช้งานได้ง่ายๆโดยรวมสคริปต์และโทรเมื่อใดก็ได้:

var trace = printStackTrace();

ฉันจะดูที่github.com/stacktracejs/stacktrace.jsเนื่องจากการใช้งานมีการเปลี่ยนแปลงเพื่อรองรับสัญญา ES6
Erez Cohen

โปรดทราบว่าตอนนี้ควรใช้: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (เวอร์ชันใหม่ยังไม่เปิดตัว)
Erez Cohen

10

นี่เป็นเพียงการปรับปรุงเล็กน้อยสำหรับรหัสที่ยอดเยี่ยมของ Konstantin มันลดค่าใช้จ่ายเล็กน้อยในการจับโยนและเพียงแค่อินสแตนซ์ Error stack:

function getStackTrace () {
    let stack = new Error().stack || '';
    stack = stack.split('\n').map(function (line) { return line.trim(); });
    return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

ฉันมักต้องการระดับเฉพาะของการติดตามสแต็ก (สำหรับคนตัดไม้แบบกำหนดเองของฉัน) ดังนั้นจึงเป็นไปได้เมื่อโทร:

getStackTrace()[2]; // get stack trace info 2 levels-deep

6

var stack = new Error().stackคุณต้องการเพียง นี่คือคำตอบ @sgouros เวอร์ชันที่เรียบง่าย

function foo() {
  bar();
}
function bar() {
  baz();
}
function baz() {
  console.log(new Error().stack);
}

foo();

อาจจะไม่ทำงานในทุกเบราว์เซอร์ (ทำงานใน Chrome)


0

ฉันพยายามรับ Stack Trace เป็นตัวแปรสตริงใน JavaScript บน NodeJS และบทช่วยสอนนี้ช่วยฉันได้ console.trace()นี้จะทำงานในสถานการณ์ของคุณเช่นกันยกเว้นสแต็คร่องรอยถูกพิมพ์ผ่านทางวัตถุข้อผิดพลาดมากกว่า

รหัสเพื่อพิมพ์การติดตามสแต็ก:

function add(x, y) {
    console.log(new Error().stack);
    return x+y;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.