How can I get a JavaScript stack trace when I throw an exception?
Asked Answered
C

25

723

If I throw a JavaScript exception myself (eg, throw "AArrggg"), how can I get the stack trace (in Firebug or otherwise)? Right now I just get the message.

edit: As many people below have posted, it is possible to get a stack trace for a JavaScript exception but I want to get a stack trace for my exceptions. For example:

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

When foo is called, I want to get a stack trace which includes the calls to foo, bar, bar.

Craps answered 26/2, 2009 at 18:36 Comment(5)
possible duplicate of Javascript exception stack traceDisentangle
Bug is still open on Firebug bug tracker since 2008: code.google.com/p/fbug/issues/detail?id=1260 - star it!Fixity
The answer should be "throw new Error('arrrgh');" see this nicely written page: devthought.com/2011/12/22/a-string-is-not-an-errorSaylor
(2013) You can now get stack traces in Firebug on Firefox even if it's simply throw 'arrrgh';, and they seem the same as with throw new Error('arrrgh');. Chrome debugger still needs throw new Error('arrrgh'); as stated, however (but Chrome seems to give much more detailed traces).Modiste
I suggest to change the title to refer to a custom exception which does not derive from Error because that seems to be the main topic of this question.Lame
B
1068

Edit 2 (2017):

In all modern browsers you can simply call: console.trace(); (MDN Reference)

Edit 1 (2013):

A better (and simpler) solution as pointed out in the comments on the original question is to use the stack property of an Error object like so:

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

This will generate output like this:

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

Giving the name of the calling function along with the URL, its calling function, and so on.

Original (2009):

A modified version of this snippet may somewhat help:

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);
}
Bantustan answered 11/3, 2009 at 18:50 Comment(19)
This seems to be the most promising so far... Creating an 'Exception', so calling an exception would be: throw Exception('message'), where the Exception function would figure out what's on the stack.Craps
Alright, well, since this is the closest thing to a correct answer, I'll accept it.Craps
I'm not sure why this isn't voted up more - the other answers didn't work that well for me. BTW, make sure not to treat arguments as an array (updated snippet here: gist.github.com/965603)Disentangle
not working in chrome, tacktrace(): [Exception: TypeError: Object #<Object> has no methodGaea
It doesn't work for me. f.arguments does not exist, in firefox at least :(Aylmar
see comment on original question: you don't need custom code, just use "throw new Error('arrrgh')"Alarum
I made an adjustment to this script in my edit that converts the arguments object to an array. Check it out!Woken
I don't see why this is upvoted as it doesn't work for me. I am trying to debug on an iphone and (new Error()).stack does not work in mobile safari on iOS7. Also arguments.join does not work as its not valid javascript since arguments is not a real array. So neither answer works.Feldspar
Error.stack is undefined in IE, only works in chrome and Mozilla firefoxSundae
f.caller will always refer to the last caller of the function. The original code will work as long as f is only invoked once. In a recursion context, you might end up into an infinite loop.Lasting
the Error.stack doesn't work with Safari 5.x at least, I don't know the newer versions. In respect to the first solution if you're coding with "use strict", it's not an option...Diagram
Note that caller is now deprecated and callee is removed from ES5 strict mode. Here's why #104098Strawberry
if var err = new Error() hasn't stack property use this form: var err; try { throw Error() } catch(e) { err = e;}Aquiver
It's possible you need a comment in the error call. new Error("stack check")Apostil
Alas Firefox lets me know that TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to themUmbles
When the exception is thrown and immediately caught, the stack property will also be available in IE. See github.com/stacktracejs/stacktrace.js/blob/master/….Hartz
> In all modern browsers you can simply call: console.trace(); (MDN Reference) This will output current stacktrace - not the stacktrace of the exception. Am I right?Selfopinionated
is there an advantage of console.trace to e.stack?Atticism
Is there a way to get the arguments passed to each function in the stack? console.log(arguments) type of thing but for each function in the stackLumpfish
G
245

Chrome/Chromium and other browsers using V8, as well as Firefox, have a convenient interface to get a stacktrace through the stack property of Error objects:

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

See details in the V8 documentation

Guano answered 16/11, 2010 at 23:47 Comment(4)
Firefox supports the .stack property too.Ursola
you can also use console.error(e.stack); so it looks like a default exception messageFootrest
This question asks specifically about exceptions that do not derive from Error and therefore do not have the stack property.Lame
Seems that this e.stack works in Expo/React native too.Jedjedd
P
89

In Firefox it seems that you don't need to throw the exception. It's sufficient to do

e = new Error();
console.log(e.stack);
Pandanus answered 27/2, 2013 at 20:38 Comment(6)
Works in mobile apps (built using JQM) as well.Abscind
Works in Chromium as well (version 43 anyway).Knox
In Firefox 59 this does not work when called via window.onerror, it shows an almost empty stack with only the onerror function.Umbles
Even better, you could do: console.log(new Error().stack) >:( >:( >:(Adversity
This will log the stack at the point where the Error object has been created, not at the point where the original exception has been thrown.Lame
That's not "throwing" an exception; it's simply constructing a new Error object.Typology
H
27

If you have firebug, there's a break on all errors option in the script tab. Once the script has hit your breakpoint, you can look at firebug's stack window:

screenshot

Hynda answered 26/2, 2009 at 22:58 Comment(1)
Hrm, that doesn't seem to work. It stops me in a debugger on errors raised by Javascript (eg, undefined variable errors), but when I throw my own exceptions I still don't get anything but the "Uncaught exception" message.Craps
W
19

A good (and simple) solution as pointed out in the comments on the original question is to use the stack property of an Error object like so:

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

This will generate output like this:

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

Giving the name of the calling function along with the URL and line number, its calling function, and so on.

I have a really elaborate and pretty solution that I have devised for a project I am currently working on and I have extracted and reworked it a bit to be generalized. Here it is:

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

Check it out on GitHub (currently v1.2)! You can use it like Console.debug("Whatever"); and it will, depending on the settings in Console, print the output and a stack trace (or just simple info/nothing extra at all). Here's an example:

Console.js

Make sure to play around with the settings in the Console object! You can add spacing between the lines of the trace and turn it off entirely. Here it is with Console.trace set to false:

No trace

You can even turn off the first bit of info shown (set Console.settings.debug.showInfo to false) or disable debugging entirely (set Console.settings.debug.enabled to false) so you never have to comment out a debug statement again! Just leave them in and this will do nothing.

Woken answered 13/8, 2013 at 17:35 Comment(0)
R
11

I don't think there's anything built in that you can use however I did find lots of examples of people rolling their own.

Rodriquez answered 26/2, 2009 at 18:39 Comment(5)
Ah, thanks -- the first link there seems like it may do (although the lack of recursion support may render it unworkable).Craps
Yeah, I didn't see any that supported recursion on first glance. I'll be curious to see if there's a good solution to that.Rodriquez
I think the second link should support recursion for Firefox and Opera because it uses the error stack trace rather than manually building one using the arguments variable. I'd love to hear if you find a cross browser solution for the recursion issue (the first article is mine). :)Hynda
Helephant: The second won't work here because, when I catch the exception, it's a "string" (ie, no "e.stack"): foo = function(){ throw "Arg"; } try { foo(); } catch (e) { /* typeof e == "string" */ } Maybe I'm throwing it wrong? (begin obligatory rant about how stupid Javascript tutorials are...)Craps
Try to throw an object: throw { name: 'NameOfException', message: 'He's dead, Jim' }.Bemock
W
9

You can access the stack (stacktrace in Opera) properties of an Error instance even if you threw it. The thing is, you need to make sure you use throw new Error(string) (don't forget the new instead of throw string.

Example:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
Whinstone answered 21/8, 2009 at 5:43 Comment(2)
stacktrace doesn't work in Opera. I can't even find something about it.Penetration
@NV: It seems stacktrace isn't on user-created errors so you should do this instead: try { 0++ } catch(e) { myStackTrace=e.stack || e.stacktrace }Whinstone
G
9

With Chrome browser, you can use console.trace method: https://developer.chrome.com/devtools/docs/console-api#consoletraceobject

Geochronology answered 3/7, 2014 at 18:7 Comment(1)
This also works on Firefox. developer.mozilla.org/en-US/docs/Web/API/console/traceGrindlay
B
7

This will give a stack trace (as array of strings) for modern Chrome, Opera, Firefox and 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);
}

Usage:

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

It excludes from the stack its own call as well as title "Error" that is used by Chrome and Firefox (but not IE).

It shouldn't crash on older browsers but just return empty array. If you need more universal solution look at stacktrace.js. Its list of supported browsers is really impressive but to my mind it is very big for that small task it is intended for: 37Kb of minified text including all dependencies.

Bontebok answered 23/1, 2015 at 20:28 Comment(0)
G
7

An update to Eugene's answer: The error object must be thrown in order for IE (specific versions?) to populate the stack property. The following should work better than his current example, and should avoid returning undefined when in IE.

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

Note 1: This sort of thing should only be done when debugging, and disabled when live, especially if called frequently. Note 2: This may not work in all browsers, but seems to work in FF and IE 11, which suits my needs just fine.

Gynaecomastia answered 12/3, 2015 at 21:7 Comment(0)
F
6

one way to get a the real stack trace on Firebug is to create a real error like calling an undefined function:

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

Or use console.error() followed by a throw statement since console.error() shows the stack trace.

Fixity answered 14/3, 2012 at 3:43 Comment(0)
K
5

This polyfill code working in modern (2017) browsers (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;
}

Other answers:

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

not working in IE 11 !

Using arguments.callee.caller - not working in strict mode in any browser!

Karilynn answered 12/8, 2017 at 22:8 Comment(0)
U
3

In Google Chrome (version 19.0 and beyond), simply throwing an exception works perfectly. For example:

/* 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();

will show the stack trace at the browser's console output:

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

Hope this help.

Unorganized answered 8/6, 2012 at 11:18 Comment(0)
P
3

function:

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

use case:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
Pyroelectric answered 23/3, 2016 at 7:9 Comment(0)
C
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>

this script will show the error

Chevy answered 30/10, 2015 at 10:46 Comment(0)
H
2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
Horsecar answered 17/3, 2017 at 16:48 Comment(2)
While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.Load
I don't see a difference to new Error().stack.split('\n').slice(2).join('\n') apart from saving to reverse the array twice.Whorled
S
1

Kind of late to the party, but, here is another solution, which autodetects if arguments.callee is available, and uses new Error().stack if not. Tested in chrome, safari and firefox.

2 variants - stackFN(n) gives you the name of the function n away from the immediate caller, and stackArray() gives you an array, stackArray()[0] being the immediate caller.

Try it out at 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();
Santee answered 13/7, 2014 at 13:38 Comment(0)
H
1

You could use this library http://www.stacktracejs.com/ . It's very good

From documentation

You can also pass in your own Error to get a stacktrace not available in IE or 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>
Henriettahenriette answered 21/10, 2014 at 21:7 Comment(1)
The linked source https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js is an old version, the newest stable version (matching the code-snippet) is here: https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.jsPudendas
T
1

Here is an answer that gives you max performance (IE 6+) and max compatibility. Compatible with 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>" );
})();
Timetable answered 5/4, 2017 at 0:52 Comment(0)
D
1

Just try

throw new Error('some error here')

This works pretty well for chrome:

enter image description here

Duston answered 22/7, 2017 at 14:6 Comment(0)
C
1

at least in Edge 2021 :

console.groupCollapsed('jjjjjjjjjjjjjjjjj')
    console.trace()
    try {
        throw "kuku"
    } catch(e) {
        console.log(e.stack)
    }
console.groupEnd()
traceUntillMe()

and you are done my friend

Cogency answered 26/1, 2021 at 21:35 Comment(0)
B
0

It is easier to get a stack trace on Firefox than it is on IE but fundamentally here is what you want to do:

Wrap the "problematic" piece of code in a try/catch block:

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

If you will examine the contents of the "error" object it contains the following fields:

e.fileName : The source file / page where the issue came from e.lineNumber : The line number in the file/page where the issue arose e.message : A simple message describing what type of error took place e.name : The type of error that took place, in the example above it should be 'TypeError' e.stack : Contains the stack trace that caused the exception

I hope this helps you out.

Brianna answered 4/3, 2009 at 2:53 Comment(1)
Wrong. He's trying to catch his OWN exceptions. If he throws "asdfg", he'll get string object, not an exception object. He's not trying to catch built-in exceptions.Azurite
V
0

I had to investigate an endless recursion in smartgwt with IE11, so in order to investigate deeper, I needed a stack trace. The problem was, that I was unable to use the dev console, because the reproduction was more difficult that way.
Use the following in a javascript method:

try{ null.toString(); } catch(e) { alert(e.stack); }
Vandiver answered 15/10, 2014 at 12:28 Comment(1)
alert((new Error()).stack);Panoptic
B
0

Wow - I don't see a single person in 6 years suggesting that we check first to see if stack is available before using it! The worst thing you can do in an error handler is throw an error because of calling something that doesn't exist.

As others have said, while stack is mostly safe to use now it is not supported in IE9 or earlier.

I log my unexpected errors and a stack trace is pretty essential. For maximum support I first check to see if Error.prototype.stack exists and is a function. If so then it is safe to use 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)
            {

            }
        };

Edit: It appears that since stack is a property and not a method you can safely call it even on older browsers. I'm still confused because I was pretty sure checking Error.prototype worked for me previously and now it doesn't - so I'm not sure what's going on.

Bonnard answered 3/10, 2015 at 7:9 Comment(0)
A
0

Using console.error(e.stack) Firefox only shows the stacktrace in logs, Chrome also shows the message. This can be a bad surprise if the message contains vital information. Always log both.

Antecede answered 22/1, 2016 at 13:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.