Re-throwing errors

# Domenic Denicola (13 years ago)

Consider:

try { doStuff(); } catch (e) { console.log("uh oh, got an e", e); throw e; }

In Node and in all browsers I've tested with, this currently loses the stack trace for e, and more importantly loses debugger step-back-ability in tools like Firebug and Web Inspector.

One solution would be to hope V8 and the browser vendors simply don't throw away this stack trace, like they do currently. This seems like a win to me, but the fact that it hasn't happened implies there must be something wrong with the idea, e.g. maybe it breaks down in less-than-trivial cases. Is that true?

If so, then in C++ and C# they solve this by saying that an empty throw is an explicit re-propagation 1. Would this be a possible feature to introduce into Harmony?

# Brendan Eich (13 years ago)

Domenic Denicola wrote:

Consider:

try { doStuff(); } catch (e) { console.log("uh oh, got an e", e); throw e; }

In Node and in all browsers I've tested with, this currently loses the stack trace for e, and more importantly loses debugger step-back-ability in tools like Firebug and Web Inspector.

One solution would be to hope V8 and the browser vendors simply don't throw away this stack trace, like they do currently. This seems like a win to me, but the fact that it hasn't happened implies there must be something wrong with the idea, e.g. maybe it breaks down in less-than-trivial cases. Is that true?

So V8 overwrites e.stack on the re-throw?

SpiderMonkey does not:

js> function f() {

try { doStuff(); } catch (e) { console.log("uh oh, got an e", e); throw e; } } js> function g() {f()}

js> function h() {g()}

js> function doStuff() {uh.oh}

js> console = {log: print} ({log:function print() {[native code]}}) js> try {h()}catch (e){E=e}

uh oh, got an e ReferenceError: uh is not defined (new ReferenceError("uh is not defined", "typein", 11)) js> e.stack

typein:15: ReferenceError: e is not defined js> E.stack "doStuff at typein:11\nf at typein:3\ng at typein:9\nh at typein:10\n at typein:14\n"

Since the explicit re-throw is not creating the exception object, it should not be mutating it to clobber the original .stack value.

# Rick Waldron (13 years ago)

On Fri, May 11, 2012 at 2:43 PM, Brendan Eich <brendan at mozilla.com> wrote:

Domenic Denicola wrote:

Consider:

try { doStuff(); } catch (e) { console.log("uh oh, got an e", e); throw e; }

In Node and in all browsers I've tested with, this currently loses the stack trace for e, and more importantly loses debugger step-back-ability in tools like Firebug and Web Inspector.

One solution would be to hope V8 and the browser vendors simply don't throw away this stack trace, like they do currently. This seems like a win to me, but the fact that it hasn't happened implies there must be something wrong with the idea, e.g. maybe it breaks down in less-than-trivial cases. Is that true?

This is fascinating, but I can't reproduce - can you confirm: gist.github.com/2662158

# Brandon Benvie (13 years ago)

V8 provides a way to capture a stack trace on a specific function (that is part of the current callstack/has live arguments and caller information the debuffer can pull from). By using Error.captureStackTrace(errorObject, functionToMakeStackFrom), you cause an accessor to be defined on the error object. The getter function in the accessor holds the string version of the stack and returns it regardless of context or whether it's called as an accessor. If you rerun Error.captureStackTrace on an error that already has a stack trace it will just overwrite it.

# Domenic Denicola (13 years ago)

Eeek, how embarrassing. This seems to have been fixed while I wasn't looking, and/or my testing wasn't as complete as I thought. I should have re-tested before emailing. My apologies for wasting everyone's time.

The debugger step-back-ability isn't there in Chrome, at least, but that's a much smaller problem.