Suggest an editImprove this articleRefine the answer for “A new error thrown inside catch”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A `catch` block does not catch its own errors: anything thrown inside it keeps travelling up the call stack.** That exception looks for the nearest outer `try...catch`, and if there is none the program dies with an uncaught error. A `finally` block still runs before the error surfaces. ```javascript try { throw new Error("failed in try"); } catch (err) { console.log("caught:", err.message); throw new Error("failed inside catch"); // nobody here catches this } ``` **Key point:** a `catch` only handles errors from its own `try`; to intercept an error raised inside the `catch` itself you need an outer `try...catch` or a nested `try` in the `catch` body.Shown above the full answer for quick recall.Answer (EN)Image**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 | Scenario | What happens | | --- | --- | | An error inside `catch` | The current `catch` does not catch it | | There is an outer `try...catch` | The error is passed there | | There is no outer `catch` | The program crashes | | There is a `finally` | It runs anyway | | The `catch` body has its own `try` | The 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.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.