public
Last active

preserving error context in a try/catch re-throw

  • Download Gist
gistfile1.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
function foo() {
// ...
nonExistent();
//
}
 
function bar() {
try {
foo();
}
catch (err) {
err.message += "\nError caught in bar()"; // this part works
throw err; // this part loses the "context" in V8, but not in all other engines
}
}
 
bar(); // an uncaught exception is gonna bubble up to the browser/engine
// but what will its context be? from inside bar() or inside foo()?

[UPDATE: turns out V8 is the only one that loses context, all other engines seem to preserve it]

By preserving "context", I'm mostly speaking of the internal context that the engine keeps about an error (more than what is exposed to the JS layer). For instance, it tracks the file, line-number, character position, etc of where an error occurs. This context is currently lost in a re-throw.

Also, I show above that I'm "decorating" the error before re-throw by adding to its message text. But in reality, there's plenty of usefulness for just being able to sort of "passively observe" that an error is bubbling up but not actually modify it at all. Perhaps you just want to do some cleanup along the way.

The preservation of context is important so that the eventual receiver of the error (or the browser/engine itself if uncaught) should be able to point back (almost like an error stack trace) to where the error originally began, not ONLY the last step that "observed" the error by catching and re-throwing.

Moreover, if code actually WANTS to interrupt or destroy the original context, this would be easy given my suggested semantics above. The code could simply do:

function bar() {
   try {
      foo();
   }
   catch (err) {
      throw new Error(...); // even `throw new Error(err);
      // this will definitely destroy/reset the error's context (stack) origination to here
   }
}

I just think it would be nice if there was a way to either preserve or not preserve. Right now, you have no choice, it will always lose the context.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.