Skip to content

Instantly share code, notes, and snippets.

@getify
Created January 30, 2011 06:35
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save getify/802625 to your computer and use it in GitHub Desktop.
preserving error context in a try/catch re-throw
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()?
@getify
Copy link
Author

getify commented Jan 30, 2011

[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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment