console.trace() genera 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 con callee.caller.name.

92
js_ 16 jul. 2011 a las 09:34

6 respuestas

La mejor respuesta

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

Entonces, una forma hacky de conseguirlo sería:

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

console.log(getStackTrace());

Normalmente, getStackTrace estaría en la pila cuando se captura. El segundo argumento allí excluye getStackTrace de ser incluido en el seguimiento de la pila.

93
chjj 16 jul. 2011 a las 05:48

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

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

foo();

Probablemente no funcionará en todos los navegadores (funciona en Chrome).

3
jcubic 9 jun. 2019 a las 10:53

Esto dará un seguimiento de la pila (como una matriz de cadenas) para Chrome moderno, Firefox, Opera e 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);
}

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 bloquearse en los navegadores más antiguos, sino simplemente 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 a la que está destinada: 37 KB de texto minimizado, incluidas todas las dependencias.

17
Konstantin Smolyanin 23 ene. 2015 a las 20:25

Error.stack es lo que necesitas. 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
34
GreenGiant 13 nov. 2014 a las 15:45

Hay una biblioteca llamada stacktrace.js que le ofrece trazas de pila cruzadas del navegador. Puede usarlo simplemente incluyendo el script y llamando en cualquier momento:

var trace = printStackTrace();
13
Zathrus Writer 10 oct. 2014 a las 14:47

Esta es solo una mejora menor al excelente código de Konstantin. Reduce un poco el gasto de lanzar y atrapar y solo 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
9
sgouros 23 mar. 2016 a las 07:55