¿Cómo obtener el resultado de console.trace () como cadena en javascript con Chrome o Firefox?

98

console.trace()muestra su resultado en la consola.
Quiero obtener los resultados como una cadena y guardarlos en un archivo.

No defino nombres para funciones y tampoco puedo obtener sus nombres callee.caller.name.

js_
fuente
1
esto no funciona en PhantomJS :(
ekkis

Respuestas:

103

No estoy seguro de Firefox, pero en v8 / chrome puedes usar un método en el constructor Error llamado captureStackTrace. ( Más info aquí )

Así que una forma hacky de conseguirlo sería:

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

console.log(getStackTrace());

Normalmente, getStackTraceestaría en la pila cuando se captura. El segundo argumento no getStackTracese incluye en el seguimiento de la pila.

chjj
fuente
18
Gracias por su información. Eso funcionó en Chrome pero no en Firefox. Así que busqué de nuevo y encontré Error().stack. Aunque los nombres de objeto y función se pierden en Firefox y el nombre de objeto se pierde en Chrome (igual que Error.captureStackTrace), Error().stackfunciona en ambos navegadores y me da suficiente información para depurar.
js_
Exactamente el mismo resultado que la respuesta de @Konstantin Smolyanin. Como resultado, los mismos detalles limitados.
Codebeat
Esta no debería ser la respuesta aceptada. La pila que obtienes aquí está "cortada" y contiene solo una "parte superior", mientras que console.trace () mostrará la pila completa. Vea un ejemplo con una profundidad de pila 30 aquí: stackoverflow.com/questions/62768598/…
mathheadinclouds
34

Error.stack es lo que necesita. Funciona en Chrome y Firefox. Por ejemplo

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

dará en 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)

y en 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
Hombre molecular
fuente
2
Gracias por tu respuesta. Pero eso funciona solo cuando ocurrió una excepción. Necesito obtener el seguimiento de la pila sin excepción.
js_
8
¿Qué hay de(new Error).stack
Jason Smith
Esto debería generar una excepción en a.debug (): es una forma cara de obtener la pila, pero debería funcionar.
fijiaaron
Este enfoque también es útil cuando se intenta obtener un rastro de algún código que solo se puede ejecutar, por ejemplo, PhantomJS o similar por cualquier motivo.
waxspin
18

Esto dará un seguimiento de la pila (como una matriz de cadenas) para Chrome, Firefox, Opera e IE10 + modernos.

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);
}

Uso:

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

Excluye de la pila su propia llamada, así como el título "Error" que utilizan Chrome y Firefox (pero no IE).

No debería fallar en navegadores más antiguos, solo devolver una matriz vacía. Si necesita una solución más universal, consulte stacktrace.js . Su lista de navegadores compatibles es realmente impresionante, pero en mi opinión es muy grande para esa pequeña tarea para la que está destinada: 37 Kb de texto minimizado, incluidas todas las dependencias.

Konstantin Smolyanin
fuente
12

Existe una biblioteca llamada stacktrace.js que le brinda seguimientos de pila entre navegadores. Puede usarlo simplemente incluyendo el script y llamando en cualquier momento:

var trace = printStackTrace();
fijiaaron
fuente
Me gustaría ver github.com/stacktracejs/stacktrace.js como la puesta en práctica ha cambiado para apoyar ES6 promesas.
Erez Cohen
Tenga en cuenta que, por ahora, esto debe usarse: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (la nueva versión aún no se ha lanzado)
Erez Cohen
9

Esta es solo una pequeña mejora del excelente código de Konstantin. Reduce un poco el costo de lanzar-atrapar y simplemente crea una instancia de la pila de errores:

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);
}

Por lo general, quiero un nivel específico de seguimiento de pila (para mi registrador personalizado), por lo que esto también es posible al llamar:

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

solo necesitas var stack = new Error().stack. esta es una versión simplificada de la respuesta de @sgouros.

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

foo();

Probablemente no funcione en todos los navegadores (funciona en Chrome).

jcubic
fuente