¿Cómo puedo obtener un seguimiento de pila de JavaScript cuando lanzo una excepción?

519

Si lanzo una excepción de JavaScript yo mismo (por ejemplo, throw "AArrggg"), ¿cómo puedo obtener el seguimiento de la pila (en Firebug o de otro modo)? En este momento acabo de recibir el mensaje.

editar : como han publicado muchas personas a continuación, es posible obtener un seguimiento de la pila para una excepción de JavaScript, pero quiero obtener un seguimiento de la pila para mis excepciones. Por ejemplo:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}

Cuando foose llama, quiero conseguir un seguimiento de pila que incluye las llamadas a foo, bar, bar.

David Wolever
fuente
1
posible duplicado de seguimiento de pila de excepción
ripper234
Bug todavía está abierto en Firebug bug tracker desde 2008: code.google.com/p/fbug/issues/detail?id=1260 - ¡ pruébalo !
Miller Medeiros
13
La respuesta debería ser "lanzar un nuevo error ('arrrgh');" vea esta página bien escrita: devthought.com/2011/12/22/a-string-is-not-an-error
elegant dice
1
(2013) Ahora puede obtener rastros de pila en Firebug en Firefox incluso si es simple throw 'arrrgh';, y parecen lo mismo que con throw new Error('arrrgh');. throw new Error('arrrgh');Sin embargo, el depurador de Chrome todavía necesita lo dicho (pero Chrome parece dar rastros mucho más detallados).
user56reinstatemonica8
26
@ChetanSastry Busqué en Google 'javascript stack trace' y este fue el primer resultado
David Sykes,

Respuestas:

756

Edición 2 (2017):

En todos los navegadores modernos, simplemente puede llamar: console.trace(); (Referencia de MDN)

Edición 1 (2013):

Una solución mejor (y más simple) como se señala en los comentarios sobre la pregunta original es usar la stackpropiedad de un Errorobjeto de esta manera:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Esto generará resultados como este:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Dar el nombre de la función de llamada junto con la URL, su función de llamada, etc.

Original (2009):

Una versión modificada de este fragmento puede ayudar un poco:

function stacktrace() { 
  function st2(f) {
    return !f ? [] : 
        st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + f.arguments.join(',') + ')']);
  }
  return st2(arguments.callee.caller);
}
Eugene Morozov
fuente
11
No estoy seguro de por qué no se vota más, las otras respuestas no me funcionaron tan bien. Por cierto, asegúrese de no tratar los argumentos como una matriz (fragmento actualizado aquí: gist.github.com/965603 )
ripper234
1
no funciona en Chrome, tacktrace (): [Excepción: TypeError: Object # <Object> no tiene método
hetaoblog
3
vea el comentario sobre la pregunta original: no necesita un código personalizado, solo use "lanzar nuevo error ('arrrgh')"
Joshua Richardson
16
Error.stack no está definido en IE, solo funciona en Chrome y Mozilla Firefox
Philipp Munin
44
Tenga en cuenta que callerahora está en desuso y calleese elimina del modo estricto ES5. He aquí por qué stackoverflow.com/questions/103598/…
PhilT
187

Tenga en cuenta que el cromo / cromo (otros navegadores que usan V8) y también Firefox tienen una interfaz conveniente para obtener un seguimiento de la pila a través de una propiedad de la pila en los objetos de error .

try {
   // Code throwing an exception
} catch(e) {
  console.log(e.stack);
}

Se aplica a las excepciones básicas, así como a las que arrojes tú mismo. (Consideró que usa la clase Error, que de todos modos es una buena práctica).

Ver detalles en la documentación de V8

Jocelyn delalande
fuente
12
Firefox también admite la .stackpropiedad.
kennytm
2
¡Desearía poder votar 100 veces! Gracias Jocelyn Realmente ayudó mucho
safrazik
1
también puede usar console.error(e.stack);para que parezca un mensaje de excepción predeterminado
Bruno Peres
80

En Firefox parece que no necesitas lanzar la excepción. Es suficiente para hacer

e = new Error();
console.log(e.stack);
Justin L.
fuente
Funciona también en aplicaciones móviles (creadas con JQM).
Samik R
También funciona en Chromium (versión 43 de todos modos).
Andy Beverley
En Firefox 59 esto no funciona cuando se llama vía window.onerror, muestra una pila casi vacía con solo la onerrorfunción.
Code4R7
Aún mejor, podría hacer: console.log(new Error().stack)> :(> :(> :(
Andrew
25

Si tiene Firebug, hay una opción de interrupción en todos los errores en la pestaña de secuencia de comandos. Una vez que el script ha alcanzado su punto de ruptura, puede mirar la ventana de la pila de Firebug:

captura de pantalla

Helefante
fuente
55
Hrm, eso no parece funcionar. Me detiene en un depurador de errores generados por Javascript (por ejemplo, errores variables indefinidos), pero cuando lanzo mis propias excepciones, sigo sin recibir nada más que el mensaje "excepción no detectada".
David Wolever
11

Una buena (y simple) solución como se señala en los comentarios sobre la pregunta original es usar la stackpropiedad de un Errorobjeto de esta manera:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Esto generará resultados como este:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Dar el nombre de la función de llamada junto con la URL y el número de línea, su función de llamada, etc.

Tengo una solución realmente elaborada y bonita que he ideado para un proyecto en el que estoy trabajando actualmente y la he extraído y reelaborado un poco para generalizarla. Aquí está:

(function(context){
    // Only global namespace.
    var Console = {
        //Settings
        settings: {
            debug: {
                alwaysShowURL: false,
                enabled: true,
                showInfo: true
            },
            stackTrace: {
                enabled: true,
                collapsed: true,
                ignoreDebugFuncs: true,
                spacing: false
            }
        }
    };

    // String formatting prototype function.
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var s = this.toString(),
                args = typeof arguments[0],
                args = (("string" == args || "number" == args) ? arguments : arguments[0]);
            if (!arguments.length)
                return s;
            for (arg in args)
                s = s.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
            return s;
        }
    }

    // String repeating prototype function.
    if (!String.prototype.times) {
        String.prototype.times = function () {
            var s = this.toString(),
                tempStr = "",
                times = arguments[0];
            if (!arguments.length)
                return s;
            for (var i = 0; i < times; i++)
                tempStr += s;
            return tempStr;
        }
    }

    // Commonly used functions
    Console.debug = function () {
        if (Console.settings.debug.enabled) {
            var args = ((typeof arguments !== 'undefined') ? Array.prototype.slice.call(arguments, 0) : []),
                sUA = navigator.userAgent,
                currentBrowser = {
                    firefox: /firefox/gi.test(sUA),
                    webkit: /webkit/gi.test(sUA),
                },
                aLines = Console.stackTrace().split("\n"),
                aCurrentLine,
                iCurrIndex = ((currentBrowser.webkit) ? 3 : 2),
                sCssBlack = "color:black;",
                sCssFormat = "color:{0}; font-weight:bold;",
                sLines = "";

            if (currentBrowser.firefox)
                aCurrentLine = aLines[iCurrIndex].replace(/(.*):/, "$1@").split("@");
            else if (currentBrowser.webkit)
                aCurrentLine = aLines[iCurrIndex].replace("at ", "").replace(")", "").replace(/( \()/gi, "@").replace(/(.*):(\d*):(\d*)/, "$1@$2@$3").split("@");

            // Show info if the setting is true and there's no extra trace (would be kind of pointless).
            if (Console.settings.debug.showInfo && !Console.settings.stackTrace.enabled) {
                var sFunc = aCurrentLine[0].trim(),
                    sURL = aCurrentLine[1].trim(),
                    sURL = ((!Console.settings.debug.alwaysShowURL && context.location.href == sURL) ? "this page" : sURL),
                    sLine = aCurrentLine[2].trim(),
                    sCol;

                if (currentBrowser.webkit)
                    sCol = aCurrentLine[3].trim();

                console.info("%cOn line %c{0}%c{1}%c{2}%c of %c{3}%c inside the %c{4}%c function:".format(sLine, ((currentBrowser.webkit) ? ", column " : ""), ((currentBrowser.webkit) ? sCol : ""), sURL, sFunc),
                             sCssBlack, sCssFormat.format("red"),
                             sCssBlack, sCssFormat.format("purple"),
                             sCssBlack, sCssFormat.format("green"),
                             sCssBlack, sCssFormat.format("blue"),
                             sCssBlack);
            }

            // If the setting permits, get rid of the two obvious debug functions (Console.debug and Console.stackTrace).
            if (Console.settings.stackTrace.ignoreDebugFuncs) {
                // In WebKit (Chrome at least), there's an extra line at the top that says "Error" so adjust for this.
                if (currentBrowser.webkit)
                    aLines.shift();
                aLines.shift();
                aLines.shift();
            }

            sLines = aLines.join(((Console.settings.stackTrace.spacing) ? "\n\n" : "\n")).trim();

            trace = typeof trace !== 'undefined' ? trace : true;
            if (typeof console !== "undefined") {
                for (var arg in args)
                    console.debug(args[arg]);

                if (Console.settings.stackTrace.enabled) {
                    var sCss = "color:red; font-weight: bold;",
                        sTitle = "%c Stack Trace" + " ".times(70);

                    if (Console.settings.stackTrace.collapsed)
                        console.groupCollapsed(sTitle, sCss);
                    else
                        console.group(sTitle, sCss);

                    console.debug("%c" + sLines, "color: #666666; font-style: italic;");

                    console.groupEnd();
                }
            }
        }
    }
    Console.stackTrace = function () {
        var err = new Error();
        return err.stack;
    }

    context.Console = Console;
})(window);

¡Compruébalo en GitHub (actualmente v1.2)! Puede usarlo como Console.debug("Whatever");y, según la configuración Console, imprimirá el resultado y un seguimiento de la pila (o simplemente información simple / nada extra). Aquí hay un ejemplo:

Console.js

¡Asegúrate de jugar con la configuración del Consoleobjeto! Puede agregar espacio entre las líneas de la traza y desactivarlo por completo. Aquí está con el Console.traceconjunto para false:

Sin rastro

Incluso puede desactivar el primer bit de información que se muestra (establecer Console.settings.debug.showInfoen false) o deshabilitar la depuración por completo (establecer Console.settings.debug.enableden false) para que nunca tenga que volver a comentar una declaración de depuración. Solo déjelos adentro y esto no hará nada.

Gabriel Nahmias
fuente
10

No creo que haya nada incorporado que pueda usar, sin embargo, encontré muchos ejemplos de personas rodando por su cuenta.

Mark Biek
fuente
Ah, gracias, el primer enlace parece que puede funcionar (aunque la falta de soporte de recursividad puede hacer que no funcione).
David Wolever
Sí, no vi nada que apoyara la recursión a primera vista. Tendré curiosidad por ver si hay una buena solución para eso.
Mark Biek
1
Creo que el segundo enlace debería admitir la recursividad para Firefox y Opera porque usa el seguimiento de la pila de errores en lugar de construir uno manualmente usando la variable de argumentos. Me encantaría saber si encuentra una solución de navegador cruzado para el problema de recurrencia (el primer artículo es mío). :)
Helephant
Helephant: El segundo no funcionará aquí porque, cuando atrapo la excepción, es una "cadena" (es decir, no "e.stack"): foo = function () {throw "Arg"; } prueba {foo (); } catch (e) {/ * typeof e == "string" * /} ¿Tal vez lo estoy tirando mal? (comience la crítica obligatoria sobre cuán estúpidos son los tutoriales de Javascript ...)
David Wolever
Trate de lanzar un objeto: throw { name: 'NameOfException', message: 'He's dead, Jim' }.
Aaron Digulla
7

Puede acceder a las propiedades stack( stacktraceen Opera) de una Errorinstancia incluso si la arrojó. La cuestión es que debe asegurarse de usar throw new Error(string)(no olvide lo nuevo en lugar de) throw string.

Ejemplo:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
Eli Gray
fuente
stacktrace no funciona en Opera. Ni siquiera puedo encontrar algo al respecto.
NVI
@NV: Parece que stacktrace no está en los errores creados por el usuario, por lo que debería hacer esto en su lugar: intente {0 ++} catch (e) {myStackTrace = e.stack || e.stacktrace}
Eli Gray
7

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

Konstantin Smolyanin
fuente
7

Una actualización de la respuesta de Eugene: el objeto de error debe ser lanzado para que IE (¿versiones específicas?) Llene la stackpropiedad. Lo siguiente debería funcionar mejor que su ejemplo actual, y debería evitar regresar undefinedcuando esté en IE.

function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.stack;
  }
}

Nota 1: Este tipo de cosas solo se deben hacer al depurar y deshabilitarlas cuando está activo, especialmente si se llama con frecuencia. Nota 2: Esto puede no funcionar en todos los navegadores, pero parece funcionar en FF e IE 11, lo que se adapta perfectamente a mis necesidades.

Patrick Seymour
fuente
6

Una forma de obtener un seguimiento real de la pila en Firebug es crear un error real como llamar a una función indefinida:

function foo(b){
  if (typeof b !== 'string'){
    // undefined Error type to get the call stack
    throw new ChuckNorrisError("Chuck Norris catches you.");
  }
}

function bar(a){
  foo(a);
}

foo(123);

O use console.error()seguido de una throwdeclaración ya que console.error()muestra el seguimiento de la pila.

Miller Medeiros
fuente
4

Este código polyfill funciona en navegadores modernos (2017) (IE11, Opera, Chrome, FireFox, Yandex):

printStackTrace: function () {
    var err = new Error();
    var stack = err.stack || /*old opera*/ err.stacktrace || ( /*IE11*/ console.trace ? console.trace() : "no stack info");
    return stack;
}

Otras respuestas:

function stackTrace() {
  var err = new Error();
  return err.stack;
}

no funciona en IE 11!

Utilizando argumentos.callee.caller : ¡no funciona en modo estricto en ningún navegador!

Petr Varyagin
fuente
3

En Google Chrome (versión 19.0 y posteriores), simplemente lanzar una excepción funciona perfectamente. Por ejemplo:

/* file: code.js, line numbers shown */

188: function fa() {
189:    console.log('executing fa...');
190:    fb();
191: }
192:
193: function fb() {
194:    console.log('executing fb...');
195:    fc()
196: }
197:
198: function fc() {
199:    console.log('executing fc...');
200:    throw 'error in fc...'
201: }
202:
203: fa();

mostrará el seguimiento de la pila en la salida de la consola del navegador:

executing fa...                         code.js:189
executing fb...                         code.js:194
executing fc...                         cdoe.js:199
/* this is your stack trace */
Uncaught error in fc...                 code.js:200
    fc                                  code.js:200
    fb                                  code.js:195
    fa                                  code.js:190
    (anonymous function)                code.js:203

Espero que esto ayude.

Rabih Kodeih
fuente
3

función:

function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}

caso de uso:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
Jaskey
fuente
2
<script type="text/javascript"
src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

este script mostrará el error

Amir Buzo
fuente
2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
Denis Orlov
fuente
2
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta.
Donald Duck
1

Un poco tarde para la fiesta, pero, aquí hay otra solución, que detecta automáticamente si argumentos.callee está disponible, y usa el nuevo Error (). Stack si no. Probado en Chrome, Safari y Firefox.

2 variantes: stackFN (n) le da el nombre de la función n lejos del llamador inmediato, y stackArray () le da una matriz, siendo stackArray () [0] el llamador inmediato.

Pruébelo en http://jsfiddle.net/qcP9y/6/

// returns the name of the function at caller-N
// stackFN()  = the immediate caller to stackFN
// stackFN(0) = the immediate caller to stackFN
// stackFN(1) = the caller to stackFN's caller
// stackFN(2) = and so on
// eg console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
function stackFN(n) {
    var r = n ? n : 0, f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (r-- >= 0) {
            tl(")");
        }
        tl(" at ");
        tr("(");
        return s;
    } else {
        if (!avail) return null;
        s = "f = arguments.callee"
        while (r>=0) {
            s+=".caller";
            r--;   
        }
        eval(s);
        return f.toString().split("(")[0].trim().split(" ")[1];
    }
}
// same as stackFN() but returns an array so you can work iterate or whatever.
function stackArray() {
    var res=[],f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (s.indexOf(")")>=0) {
            tl(")");
            s2= ""+s;
            tl(" at ");
            tr("(");
            res.push(s);
            s=""+s2;
        }
    } else {
        if (!avail) return null;
        s = "f = arguments.callee.caller"
        eval(s);
        while (f) {
            res.push(f.toString().split("(")[0].trim().split(" ")[1]);
            s+=".caller";
            eval(s);
        }
    }
    return res;
}


function apple_makes_stuff() {
    var retval = "iPhones";
    var stk = stackArray();

    console.log("function ",stk[0]+"() was called by",stk[1]+"()");
    console.log(stk);
    console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
    return retval;
}



function apple_makes (){
    return apple_makes_stuff("really nice stuff");
}

function apple () {
    return apple_makes();
}

   apple();
no sincronizado
fuente
1

Puede usar esta biblioteca http://www.stacktracejs.com/ . Es muy bueno

De la documentación

También puede pasar su propio error para obtener un stacktrace no disponible en IE o Safari 5-

<script type="text/javascript" src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>
Doua Beri
fuente
La fuente vinculada https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.jses una versión antigua, la versión estable más nueva (que coincide con el fragmento de código) está aquí:https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.js
Frederic Leitenberger
1

Aquí hay una respuesta que le brinda el máximo rendimiento (IE 6+) y la máxima compatibilidad. Compatible con IE 6!

    function stacktrace( log_result ) {
    	var trace_result;
    // IE 6 through 9 compatibility
    // this is NOT an all-around solution because
    // the callee property of arguments is depredicated
    /*@cc_on
    	// theese fancy conditinals make this code only run in IE
    	trace_result = (function st2(fTmp) {
    		// credit to Eugene for this part of the code
    		return !fTmp ? [] :
    			st2(fTmp.caller).concat([fTmp.toString().split('(')[0].substring(9) + '(' + fTmp.arguments.join(',') + ')']);
    	})(arguments.callee.caller);
    	if (log_result) // the ancient way to log to the console
    		Debug.write( trace_result );
    	return trace_result;
    @*/
    	console = console || Console;	// just in case
    	if (!(console && console.trace) || !log_result){
    		// for better performance in IE 10
    		var STerror=new Error();
    		var unformated=(STerror.stack || STerror.stacktrace);
    		trace_result = "\u25BC console.trace" + unformated.substring(unformated.indexOf('\n',unformated.indexOf('\n'))); 
    	} else {
    		// IE 11+ and everyone else compatibility
    		trace_result = console.trace();
    	}
    	if (log_result)
    		console.log( trace_result );
    	
    	return trace_result;
    }
// test code
(function testfunc(){
	document.write( "<pre>" + stacktrace( false ) + "</pre>" );
})();

Jack Giffin
fuente
0

Es más fácil obtener un seguimiento de la pila en Firefox que en IE, pero fundamentalmente esto es lo que desea hacer:

Envuelva el fragmento de código "problemático" en un bloque try / catch:

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}

Si va a examinar el contenido del objeto "error", contiene los siguientes campos:

e.fileName: el archivo / página de origen del que surgió el problema e.lineNumber: el número de línea en el archivo / página donde surgió el problema e.message: un mensaje simple que describe qué tipo de error ocurrió e.name: el tipo de error que tuvo lugar, en el ejemplo anterior debería ser 'TypeError' e.stack: contiene el seguimiento de la pila que causó la excepción

Espero que esto te ayude.

Miguel
fuente
1
Incorrecto. Él está tratando de atrapar sus PROPIAS excepciones. Si arroja "asdfg", obtendrá un objeto de cadena, no un objeto de excepción. No está tratando de atrapar excepciones incorporadas.
Ivan Vučica
0

Tuve que investigar una recursión sin fin en smartgwt con IE11, por lo que para investigar más a fondo, necesitaba un seguimiento de la pila. El problema era que no podía usar la consola de desarrollo, porque la reproducción era más difícil de esa manera.
Use lo siguiente en un método javascript:

try{ null.toString(); } catch(e) { alert(e.stack); }
kirilv
fuente
alerta ((nuevo error ()). stack);
rico remer
0

Wow: ¡no veo a una sola persona en 6 años sugiriendo que verifiquemos primero para ver si stackestá disponible antes de usarlo! Lo peor que puede hacer en un controlador de errores es arrojar un error por llamar a algo que no existe.

Como han dicho otros, aunque stackes más seguro de usar ahora, no es compatible con IE9 o versiones anteriores.

Registro mis errores inesperados y un seguimiento de la pila es bastante esencial. Para obtener el máximo soporte, primero verifico si Error.prototype.stackexiste y si es una función. Si es así, es seguro de usar error.stack.

        window.onerror = function (message: string, filename?: string, line?: number, 
                                   col?: number, error?: Error)
        {
            // always wrap error handling in a try catch
            try 
            {
                // get the stack trace, and if not supported make our own the best we can
                var msg = (typeof Error.prototype.stack == 'function') ? error.stack : 
                          "NO-STACK " + filename + ' ' + line + ':' + col + ' + message;

                // log errors here or whatever you're planning on doing
                alert(msg);
            }
            catch (err)
            {

            }
        };

Editar: Parece que, dado que stackes una propiedad y no un método, puede llamarlo con seguridad incluso en navegadores antiguos. Todavía estoy confundido porque estaba bastante seguro de que la verificación Error.prototypefuncionó para mí anteriormente y ahora no lo hace, así que no estoy seguro de lo que está sucediendo.

Simon_Weaver
fuente
0

Usando console.error(e.stack)Firefox solo muestra el stacktrace en los registros, Chrome también muestra el mensaje. Esto puede ser una mala sorpresa si el mensaje contiene información vital. Siempre registre ambos.

Christophe Roussy
fuente
0

Sólo inténtalo

throw new Error('some error here')

Esto funciona bastante bien para Chrome:

ingrese la descripción de la imagen aquí

Anthony Zhan
fuente