Handle Failure and Finish Cleanup

Handle Failure and Finish Cleanup

try runs an operation, catch handles a thrown failure and finally runs as control leaves the construct. A finally block is useful for cleanup, but returning from it can replace an earlier result.

Before this topic, review Recognize Syntax, Reference and Logic Errors if its terms are unfamiliar.

What you’ll learn

  • Explain handle failure and finish cleanup through the school example.
  • Trace the shown operations and distinguish their result from displayed output.
  • Make the practice change and explain its consequence: The message changes, while cleanup still executes after the catch.

Work through the school example

This is JavaScript using language features and the host console. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.

JavaScript · school.js · complete example

try {
  throw new Error("Invalid mark");
} catch (error) {
  console.log(error.message);
} finally {
  console.log("Finished");
}

Expected output

Invalid mark
Finished
Run in JavaScript compiler →

What is try-catch-finally in JavaScript?

In JavaScript, try, catch, and finally are used for handling runtime errors in a graceful way. They prevent your code from crashing by catching exceptions and letting you decide how to respond.

Syntax:

try {
  // Code that might throw an error
} catch (error) {
  // Code to handle the error
} finally {
  // Code that runs no matter what
}

Example 1: Basic try-catch

This example demonstrates what happens when we try to call an undefined function.

try {
  someUndefinedFunction();
  console.log("This line won't be executed.");
} catch (err) {
  console.log("An error occurred:", err.message);
}
An error occurred: someUndefinedFunction is not defined

Why does this happen?

Because someUndefinedFunction doesn't exist, JavaScript throws a ReferenceError. The catch block catches this error and allows us to log or handle it instead of letting the program crash.

Example 2: Using finally

Let's extend our previous example with a finally block to ensure some code runs regardless of an error.

try {
  console.log("Trying to execute risky code...");
  someUndefinedFunction();
} catch (error) {
  console.log("Caught an error:", error.message);
} finally {
  console.log("Finally block always runs.");
}
Trying to execute risky code...
Caught an error: someUndefinedFunction is not defined
Finally block always runs.

Question:

When does the finally block execute?

Answer: The finally block always runs—whether or not an error was thrown or caught. It is typically used for cleanup operations like closing files or releasing resources.

Example 3: No error in try block

What happens if there is no error in the try block?

try {
  console.log("No errors here!");
} catch (err) {
  console.log("Error caught:", err.message);
} finally {
  console.log("This still runs!");
}
No errors here!
This still runs!

Example 4: Re-throwing an error after catch

Sometimes you may want to catch an error, do something, and then re-throw it for higher-level handlers.

function processUserData() {
  try {
    JSON.parse("This is not JSON");
  } catch (err) {
    console.log("Logging error locally:", err.message);
    throw err; // Re-throwing error
  }
}

try {
  processUserData();
} catch (e) {
  console.log("Caught again at higher level:", e.message);
}
Logging error locally: Unexpected token T in JSON at position 0
Caught again at higher level: Unexpected token T in JSON at position 0

Points to Remember

  • try is used to wrap code that may throw errors.
  • catch handles the error and prevents the program from crashing.
  • finally always executes—used for cleanup logic.
  • You can nest try-catch-finally blocks and re-throw errors if needed.

Common Use Cases

  • Parsing user input (like JSON)
  • Working with external APIs that might fail
  • Cleanup tasks (closing database connections, timers, etc.)

Quick Quiz

Q: Will finally execute if there is a return statement in try?

A: Yes. finally always executes, even if try or catch returns a value or throws an error.

function demo() {
  try {
    return "Returning from try";
  } catch (e) {
    return "Returning from catch";
  } finally {
    console.log("Finally runs!");
  }
}

console.log(demo());
Finally runs!
Returning from try

Recognize the important boundary

Catching does not undo earlier changes. Do not return from finally unless overriding the earlier return is intentional.

Try a small variation

JavaScript · original source for practice

try {
  throw new Error("Invalid mark");
} catch (error) {
  console.log(error.message);
} finally {
  console.log("Finished");
}

Your task: Replace Invalid mark with Missing mark. Predict the result before running the edited program.

The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.

Worked answer and reasoning

The message changes, while cleanup still executes after the catch.

JavaScript · complete worked variation

try {
  throw new Error("Missing mark");
} catch (error) {
  console.log(error.message);
} finally {
  console.log("Finished");
}

Expected output

Missing mark
Finished
Run in JavaScript compiler →

Predict the original program

JavaScript · original program for this question

try {
  throw new Error("Invalid mark");
} catch (error) {
  console.log(error.message);
} finally {
  console.log("Finished");
}
What does the original JavaScript program display, in order?
Choose one answer. You can try again.

Answer and explanation

Invalid mark → Finished

try runs an operation, catch handles a thrown failure and finally runs as control leaves the construct. A finally block is useful for cleanup, but returning from it can replace an earlier result. Catching does not undo earlier changes. Do not return from finally unless overriding the earlier return is intentional.

Keep the useful idea

try runs an operation, catch handles a thrown failure and finally runs as control leaves the construct. A finally block is useful for cleanup, but returning from it can replace an earlier result.

Check your variation against this explanation: The message changes, while cleanup still executes after the catch.

Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Debug a Calculation →