JavaScript Error Handling


Why Error Handling Matters

Errors happen! Maybe the user enters invalid data, a server is down, or a function receives the wrong input.

JavaScript provides try...catch blocks to handle errors gracefully instead of crashing the program.

Syntax: try...catch

try {
  // Code that might throw an error
} catch (error) {
  // Code to handle the error
}

Example:

try {
  let result = someUndefinedVariable + 10;
} catch (err) {
  console.log("Something went wrong:", err.message);
}

Output:

Something went wrong: someUndefinedVariable is not defined

Without try...catch, this error would stop the rest of your JavaScript from running!

The finally Block

finally always runs — whether there was an error or not.

try {
  console.log("Trying something risky");
} catch (err) {
  console.log("Error happened!");
} finally {
  console.log("Always runs!");
}

Use finally to clean up resources, close files/connections, or reset states.

The throw Keyword

You can throw custom errors manually using throw.

function divide(a, b) {
  if (b === 0) {
    throw new Error("Cannot divide by zero");
  }
  return a / b;
}

try {
  console.log(divide(10, 0));
} catch (err) {
  console.log("Caught:", err.message);
}

Built-in Error Types

Error Type Description
ReferenceError Variable not defined
TypeError Wrong type or invalid operation
SyntaxError Invalid JavaScript syntax
RangeError Number out of allowable range
EvalError Error in eval() function
URIError Invalid URI functions like decodeURI()

Real-Life Use Case: Form Validation

function validateAge(age) {
  if (isNaN(age)) throw new Error("Age must be a number");
  if (age < 18) throw new Error("You must be at least 18");
  return true;
}
                              
try {
  validateAge("hello");
} catch (err) {
  console.log("Validation error:", err.message);
}

Nesting and Re-throwing Errors

You can catch an error, handle it partly, and re-throw it.

try {
  try {
    throw new Error("Original error");
  } catch (err) {
    console.log("Logging:", err.message);
    throw err; // Re-throwing
  }
} catch (e) {
  console.log("Final catch:", e.message);
}

Optional: Using try...catch with async/await

async function fetchData() {
  try {
    let res = await fetch("https://invalid-url.com");
    let data = await res.json();
  } catch (error) {
    console.log("Network or JSON error:", error.message);
  }
}

🧪 Practice Exercise:

Task:

  1. Write a function that throws an error if the argument is not a string.
  2. Use try...catch...finally to divide two numbers.
  3. Validate a name field in a form — throw if it's empty.
  4. Write a nested try...catch block and re-throw the error.
  5. Handle a fetch() request error using try/catch.