Як отримати результат console.trace () як рядок у javascript з chrome або firefox?


98

console.trace()виводить свій результат на консоль.
Я хочу отримати результати у вигляді рядка та зберегти їх у файл.

Я не визначаю імена функцій, і я також не можу отримати їх імена callee.caller.name.


1
це не працює у PhantomJS :(
ekkis

Відповіді:


103

Я не впевнений у Firefox, але у v8 / chrome ви можете використовувати метод у конструкторі помилок, який називається 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

34

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_

8
А що(new Error).stack
JasonSmith

Це повинно викликати виняток на a.debug () - це дорогий спосіб отримати стек, але він повинен працювати.
fijiaaron

Цей підхід також стає в нагоді при спробі отримати трасування з якогось коду, який може працювати лише на, наприклад, PhantomJS чи тому подібному з будь-якої причини.
waxspin

18

Це дасть трасування стека (як масив рядків) для сучасних 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 . Список підтримуваних браузерів справді вражає, але, на мою думку, він дуже великий для того невеликого завдання, для якого він призначений: 37 Кб зменшеного тексту, включаючи всі залежності.


12

Існує бібліотека stacktrace.js, яка дає вам перехресні стеки браузера. Ви можете використовувати його, просто включивши сценарій і зателефонувавши в будь-який момент:

var trace = printStackTrace();

Я б подивився github.com/stacktracejs/stacktrace.js, оскільки реалізація змінилася, щоб підтримати обіцянки ES6.
Ерез Коен,

Зауважте, що наразі це слід використовувати: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (нова версія ще не випущена)
Ерез Коен,

9

Це лише незначне вдосконалення чудового кодексу Костянтина. Це трохи скорочує за рахунок закидання і просто створює екземпляр стека Error:

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

5

вам потрібно лише var stack = new Error().stack. це спрощена версія відповіді @sgouros.

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

foo();

Можливо, це буде працювати не в кожному браузері (працює в Chrome).

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