1.4 Module 1 · Operators, Methods & Keywords

Exception Handling

Learn how to use try, catch, and finally to handle runtime errors gracefully — keeping your program running instead of crashing.

1

Definition

Exception Handling in JavaScript is a mechanism used to handle runtime errors using constructs like try, catch, and finally, ensuring the program continues to run without crashing.

Without exception handling, a single error stops all code from running. With it, you control exactly what happens when something goes wrong.

2

Simple Way

Exception handling means: "If something breaks, don't crash — handle it smartly."

try Run code that might throw an error
catch Handle the error if one occurs — don't let it crash the page
finally Always runs regardless of success or failure
throw Manually trigger a custom error
3

Code Examples

Example 1 — Basic try...catch
try {
    let result = 10 / 0;
    console.log(result);   // Infinity — not an error in JS
} catch (error) {
    console.log("Something went wrong:", error.message);
}
Output
Click ▶ Run to execute
Explanation
  • try wraps code that might fail
  • catch runs only if an error is thrown — here none is, so it's skipped
  • In JavaScript, dividing by zero gives Infinity, not an error
Example 2 — Handling a Real Error
try {
    console.log(userName); // userName is not defined
} catch (error) {
    console.log("Error:", error.message);
}
Output
Click ▶ Run to execute
Explanation
  • Accessing an undefined variable throws a ReferenceError
  • error.message gives the human-readable reason for the error
  • Without try...catch this would crash all code below it
Example 3 — finally Block
try {
    let num = 5;
    console.log(num);
} catch (error) {
    console.log("Error occurred");
} finally {
    console.log("This always runs");
}
Output
Click ▶ Run to execute
Explanation
  • finally runs no matter what — error or no error
  • Use it to clean up resources: close files, hide loading spinners, log attempts
Example 4 — Custom Error with throw
function checkAge(age) {
    try {
        if (age < 18) {
            throw new Error("You are underage");
        }
        console.log("Access granted");
    } catch (error) {
        console.log("Blocked:", error.message);
    }
}

checkAge(16);
checkAge(21);
Output
Click ▶ Run to execute
Explanation
  • throw lets you create your own errors with custom messages
  • new Error("...") is preferred over throwing a plain string
  • The thrown error is caught by the catch block immediately
4

Real-Life Example

Think of an online payment process:

try
Payment process starts — charge the card
catch
Payment fails — show a friendly error, don't crash
finally
Show receipt or retry option — always happens
throw
Insufficient balance — raise a custom error
5

HTML + JavaScript Example

A real-world input validator — it uses throw to raise custom errors and catch to display them to the user without crashing the page.

Live in Browser
<!DOCTYPE html>
<html>
<head><title>Exception Handling</title></head>
<body style="font-family:sans-serif;padding:20px;background:#f8f9fa">

  <h2>Enter a number</h2>
  <input type="text" id="num" placeholder="e.g. 42">
  <button onclick="checkNumber()">Check</button>
  <p id="result" style="margin-top:10px;font-weight:600"></p>

  <script>
  function checkNumber() {
    let value = document.getElementById("num").value;
    let out   = document.getElementById("result");

    try {
      if (value === "") throw new Error("Input cannot be empty");

      let number = Number(value);
      if (isNaN(number)) throw new Error("Not a valid number");

      out.style.color = "green";
      out.innerText   = "Valid number: " + number;
    } catch (error) {
      out.style.color = "red";
      out.innerText   = "Error: " + error.message;
    } finally {
      console.log("Validation attempted");
    }
  }
  </script>

</body>
</html>
Live Preview
6

Tasks (Practice)

Easy Task 1 — Safe division
Starter code
function divide(a, b) {
    // your code here
}

console.log(divide(10, 2));
console.log(divide(10, 0));
  • Use try...catch inside divide()
  • If b is 0, throw new Error("Cannot divide by zero")
  • Otherwise return the result and log it
Medium Task 2 — Age eligibility checker
Starter code
function checkEligibility(age) {
    // your code here
}

checkEligibility(20);
checkEligibility(15);
  • Throw a custom error if age < 18
  • Print "Eligible" if the age is valid
  • Use catch to print the error message
  • Add finally to always log "Check complete"
7

MCQs

Q1
Which block handles errors in a try...catch statement?
  • A try
  • B catch
  • C finally
  • D throw
💡 B is correct. The catch block receives the error object and decides what to do with it — log it, show a message, or recover.
Q2
What does the finally block do?
  • A Runs only if an error occurs
  • B Runs only if no error occurs
  • C Always runs, error or not
  • D Stops execution
💡 C is correct. finally always executes — it's the right place for cleanup code like closing connections or hiding loading spinners.
Q3
What is throw used for?
  • A Ignore an error
  • B Create and raise a custom error
  • C Stop all code permanently
  • D Print a message to the console
💡 B is correct. throw lets you raise your own errors with custom messages — useful for enforcing business rules like age limits or required fields.
8

Pro Tips & Extra Knowledge

  • 01

    Always throw an Error object instead of a plain string — you get a stack trace and a .message property:

    Prefer Error objects
    // Avoid
    throw "Invalid input";
    
    // Prefer
    throw new Error("Invalid input");
    
    try {
        throw new Error("Invalid input");
    } catch (e) {
        console.log(e.message); // "Invalid input"
        console.log(e instanceof Error); // true
    }
    Output
    Click ▶ Run to execute
  • 02

    Don't overuse try...catch — wrap only the risky operation, not your entire program. Catching everything hides bugs you need to know about.

  • 03

    Validate inputs before risky operations — use isNaN() for numbers and check for empty strings up front:

    Input validation pattern
    function parseAmount(input) {
        if (input === "") throw new Error("Field is required");
        if (isNaN(Number(input))) throw new Error("Must be a number");
        return Number(input);
    }
    
    try {
        console.log(parseAmount("42"));
        console.log(parseAmount("abc"));
    } catch (e) {
        console.log("Caught:", e.message);
    }
    Output
    Click ▶ Run to execute
  • 04

    Keep error messages user-friendly in the UI — log the technical details to the console, show a simple message to the user:

    Separate user-facing and dev-facing messages
    try {
        // risky operation
    } catch (e) {
        console.error("Debug:", e.message);           // for developer
        showToUser("Something went wrong. Try again."); // for user
    }
Mini Challenge

What gets printed, and in what order? Predict before running.

What is the output?
try {
    let x = y + 10; // y is not defined
} catch (e) {
    console.log("Error handled");
} finally {
    console.log("Done");
}
Output
Think first, then run!
Step-by-Step Explanation
// Step 1: try block runs → y is not defined → ReferenceError thrown
// Step 2: catch block catches it → prints "Error handled"
// Step 3: finally always runs → prints "Done"

// Output (in order):
// "Error handled"
// "Done"

// Key insight: finally runs even after catch — it is truly unconditional.
1.3 Internal vs External Scripts