Handle one error locally and pass another outward.

nested-handling Nested `try` blocks can handle some failures close to where they happen and allow other failures to move outward.

Nested Handling

mode
nested_handling.js
Replay: real traced execution (multi-file project)
const mode = "inner";
let status = "";

try {
  try {
    if (mode === "inner") {
      throw new Error("inner");
    }
    if (mode === "outer") {
      throw new Error("outer");
    }
    status = "ok";
  } catch (error) {
    if (error.message === "outer") {
      throw error;
    }
    status = "inner handled";
  }
} catch (error) {
  status = "outer handled";
}

console.log("mode=" + mode);
console.log("status=" + status);
const mode = "outer";
let status = "";

try {
  try {
    if (mode === "inner") {
      throw new Error("inner");
    }
    if (mode === "outer") {
      throw new Error("outer");
    }
    status = "ok";
  } catch (error) {
    if (error.message === "outer") {
      throw error;
    }
    status = "inner handled";
  }
} catch (error) {
  status = "outer handled";
}

console.log("mode=" + mode);
console.log("status=" + status);
const mode = "ok";
let status = "";

try {
  try {
    if (mode === "inner") {
      throw new Error("inner");
    }
    if (mode === "outer") {
      throw new Error("outer");
    }
    status = "ok";
  } catch (error) {
    if (error.message === "outer") {
      throw error;
    }
    status = "inner handled";
  }
} catch (error) {
  status = "outer handled";
}

console.log("mode=" + mode);
console.log("status=" + status);
  1. mode ← inner, status ← (empty)

    1const mode→ inner = "inner"; //@mode="outer", "ok"2let status→ (empty) = "";
  2. if (mode === "inner")

    4try {5  try {6    if (modeinner === "inner") {7      throw new Error("inner");8    }
  3. status ← inner handled

    12  status = "ok";13} catch (error) {14  if (error.message === "outer") {15    throw error;16  }17  status = "inner handled";18}
    values this stepinner handledstatus
  4. console.log("mode=" + mode);

    20  status = "outer handled";21}2223console.log("mode=" + modeinner);24console.log("status=" + statusinner handled);
    outputmode=inner
    status=inner handled
  1. mode ← outer, status ← (empty)

    1const mode→ outer = "outer";2let status→ (empty) = "";
  2. if (mode === "outer")

    7  throw new Error("inner");8}9if (modeouter === "outer") {10  throw new Error("outer");11}
  3. if (error.message === "outer")

    12  status = "ok";13} catch (error) {14  if (error.messageouter === "outer") {15    throw errorError: outer;16  }
  4. status ← outer handled

    18  }19} catch (error) {20  status = "outer handled";21}
    values this stepouter handledstatus
  5. console.log("mode=" + mode);

    20  status = "outer handled";21}2223console.log("mode=" + modeouter);24console.log("status=" + statusouter handled);
    outputmode=outer
    status=outer handled
  1. mode ← ok, status ← (empty)

    1const mode→ ok = "ok";2let status→ (empty) = "";
  2. status ← ok

    4try {5  try {6    if (mode === "inner") {7      throw new Error("inner");8    }9    if (mode === "outer") {10      throw new Error("outer");11    }12    status = "ok";13  } catch (error) {
    values this stepokstatus
  3. console.log("mode=" + mode);

    20  status = "outer handled";21}2223console.log("mode=" + modeok);24console.log("status=" + statusok);
    outputmode=ok
    status=ok