JavaScriptLesson 14 of 18

Error Handling and Debugging

Errors happen in every program, and the difference between a beginner and a developer is how they handle them. JavaScript reports problems with errors, and you can catch those errors before they stop your page. Learn to read the message, find the line, and fix the cause instead of guessing.

Errors happen in every program, and the difference between a beginner and a developer is how they handle them. JavaScript reports problems with errors, and you can catch those errors before they stop your page. Learn to read the message, find the line, and fix the cause instead of guessing.

The tool for handling errors is try catch. Wrap risky code in try, and if anything inside throws, the catch block runs instead of the script stopping. The error object that catch receives carries the message and the stack trace, the list of calls that led to the failure. Reading that trace is how you find the exact line that broke.

You can also raise your own errors with throw. Throwing is how you signal that something is wrong, like an empty form field or a value out of range. The error message you write becomes the message the catch block sees. Finally runs after try and catch no matter what, which makes it the right place to clean up.

Catching errors

Wrap code that might fail in try, and handle the failure in catch. The error object passed to catch has a message you can show and a stack you can read. Without try catch, an uncaught error stops the entire script.

JS
try {
  JSON.parse("not json"); // this throws
  console.log("Never reached");
} catch (err) {
  console.log("Problem:", err.message);
}

Throwing your own errors

throw stops the current function and hands control to the nearest catch. It is how you signal invalid input or an impossible state. Throw new Error with a clear message so the person debugging sees exactly what went wrong.

JS
function setAge(age) {
  if (age < 0) {
    throw new Error("Age cannot be negative");
  }
  return age;
}

Finally always runs

finally runs after both try and catch, whether the code succeeded or failed. Use it for cleanup: closing a connection, clearing a timer, or restoring a disabled button. It runs even if the catch throws again, so it is the reliable place to reset state.

JS
try {
  runTheRiskyStep();
} catch (err) {
  showError(err);
} finally {
  cleanup(); // always runs, success or failure
}

Syntax

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

try {
  const result = divide(10, 0);
  console.log(result);
} catch (err) {
  console.log("Calculation failed:", err.message);
}

Uncaught ReferenceError Stops All Later Code

One uncaught error stops the whole script — wrap risky code in try/catch.

JS
try{ risky() }catch(e){ console.error(e)}

Good to know

  • try catch stops errors from killing the whole script.
  • The error object has message and stack to help you debug.
  • throw raises your own errors with a custom message.
  • finally runs no matter what, so it is the place for cleanup.
  • Console error messages point to the exact line and column.
Try it Yourself Edit the code, press Run, then check what changed in the Result.
Ready
Code
Result

Practice makes it stick

Open the Playground and build your own page with the tags you just learned.

→ Open Playground