Skip to main content

A new error thrown inside catch

An error thrown inside a catch is not handled by that same catch. It travels up the call stack to the nearest outer try...catch, and if there is none it terminates the program.

Theory

TL;DR

  • A catch only catches what happened in its own try block.
  • An error thrown from the catch body goes up the stack to the next handler.
  • With no outer handler you get an uncaught error and the program dies.
  • finally always runs, even when the catch threw a new error.
  • To handle the error locally, wrap the catch body in its own try...catch.

Quick example

javascript
try { throw new Error("failed in try"); } catch (err) { console.log("caught:", err.message); // a new error right here throw new Error("failed inside catch"); }

Output:

text
caught: failed in try Uncaught Error: failed inside catch

The first error was caught, the second one had no handler and brought the program down.

What happens step by step

  1. An error is thrown in try, control moves to catch.
  2. The handling code inside catch starts running.
  3. If an error happens again inside catch, the current catch no longer catches it: it is responsible only for errors from its own try.
  4. The new error goes up the stack, to the nearest outer try...catch if there is one.
  5. If there is no outer try...catch, the program terminates with that error.

An outer try...catch catches the error from catch

To handle the new error you need another construct one level up:

javascript
try { try { throw new Error("failed in try"); } catch (err) { console.log("inner catch:", err.message); throw new Error("failed in catch"); } } catch (err) { console.log("outer catch caught:", err.message); }

Output:

text
inner catch: failed in try outer catch caught: failed in catch

Now the outer construct caught the error that happened inside the catch block.

Here is what happens without an outer handler, the error simply takes the script down:

javascript
try { throw new Error("first failure"); } catch (e) { console.log("catch:", e.message); JSON.parse("invalid json"); // SyntaxError }

Output:

text
catch: first failure Uncaught SyntaxError: Unexpected token 'i', "invalid json" is not valid JSON

finally runs no matter what

Even if a new error appeared inside catch, the finally block still runs before the error surfaces.

javascript
try { try { throw new Error("failed in try"); } catch (e) { console.log("catch:", e.message); throw new Error("failed in catch"); } finally { console.log("finally: always runs"); } } catch (e) { console.log("outer catch:", e.message); }

Output:

text
catch: failed in try finally: always runs outer catch: failed in catch

The order matters: finally first, and only then does the error reach the outer catch.

A nested try inside catch

Another option is to wrap the body of catch in its own try...catch:

javascript
try { throw new Error("failed in try"); } catch (e) { try { console.log("catch:", e.message); throw new Error("failed inside catch"); } catch (innerErr) { console.log("caught the inner one:", innerErr.message); } }

Output:

text
catch: failed in try caught the inner one: failed inside catch

This keeps errors raised inside catch under control so that nothing escapes.

Summary table

ScenarioWhat happens
An error inside catchThe current catch does not catch it
There is an outer try...catchThe error is passed there
There is no outer catchThe program crashes
There is a finallyIt runs anyway
The catch body has its own tryThe inner error is caught locally

Common mistakes

  • Assuming a catch will intercept its own throw. The handler is already active and does not catch itself.
  • Forgetting that after a throw in catch the rest of the catch body never runs.
  • Thinking a new error in catch cancels finally. finally always runs.
  • Throwing a new error and losing the original cause. Pass it along: throw new Error("wrapper", { cause: err }).
  • Throwing from finally. Such a throw overrides the exception that was already on its way out, and the original error disappears without a trace.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.