JavaScript Tutorial menu

JavaScript Error Handling

Errors happen in every program. Good code expects them and handles them, so the page does not break for the user.

What Happens Without Handling

When an error happens and nobody handles it, JavaScript stops running the rest of that script. Any code after the error line never runs.

Example

javascript
console.log("Start");
const user = null;
console.log(user.name);     // TypeError: the script stops here
console.log("End");          // never runs

try and catch

Put code that might fail inside try. If an error happens, JavaScript jumps straight to catch, and the program keeps going.

Example

html
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
const out = document.getElementById("demo");

try {
  const user = null;
  out.innerHTML = user.name;
} catch (error) {
  out.innerHTML = "Something went wrong.<br>" +
                  "Type: " + error.name + "<br>" +
                  "Message: " + error.message;
}

out.innerHTML += "<br>The page still works!";
</script>

</body>
</html>
Try it Yourself »
Output
Something went wrong.
Type: TypeError
Message: Cannot read properties of null (reading 'name')
The page still works!

The error object always has:

  • name: the type of error, like "TypeError"
  • message: a description of what went wrong
  • stack: where in the code it happened (useful for debugging)

finally

Code in finally runs always: after try succeeds, and after catch handles an error. Use it for clean-up, like hiding a loading message.

Example

javascript
function divideBill(total, people) {
  try {
    if (people <= 0) throw new Error("Number of people must be at least 1");
    return Math.round(total / people);
  } catch (error) {
    console.log("Error:", error.message);
    return 0;
  } finally {
    console.log("Calculation finished");
  }
}

console.log(divideBill(3000, 4));
console.log(divideBill(3000, 0));
Output
Calculation finished
750
Error: Number of people must be at least 1
Calculation finished
0

finally runs even when try or catch contains return.

Throwing Your Own Errors

Use throw to stop when something is wrong. Always throw an Error object (not a plain string), so you get a name, message and stack.

Example

javascript
function setAge(age) {
  if (typeof age !== "number") {
    throw new TypeError("Age must be a number");
  }
  if (age < 5 || age > 100) {
    throw new RangeError("Age must be between 5 and 100");
  }
  return age;
}

Built-in Error Types

TypeHappens when
SyntaxErrorThe code is written wrongly (also from JSON.parse with bad text)
ReferenceErrorYou use a variable that does not exist
TypeErrorA value is the wrong type, like calling null.name or 5()
RangeErrorA number is outside the allowed range
ErrorThe general type for your own errors

Custom Error Classes

For bigger programs, create your own error types by extending Error. Then you can check which error happened with instanceof.

Example

html
<!DOCTYPE html>
<html>
<body>

<input id="amount" type="number" placeholder="Amount in Rs">
<button id="pay">Withdraw</button>
<p id="msg"></p>

<script>
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

class BalanceError extends Error {
  constructor(needed) {
    super("Not enough balance. You need Rs " + needed + " more.");
    this.name = "BalanceError";
    this.needed = needed;
  }
}

let balance = 5000;

function withdraw(amount) {
  if (!amount || amount <= 0) throw new ValidationError("Enter an amount above 0.");
  if (amount > balance) throw new BalanceError(amount - balance);
  balance -= amount;
  return balance;
}

document.getElementById("pay").addEventListener("click", () => {
  const msg = document.getElementById("msg");
  try {
    const left = withdraw(Number(document.getElementById("amount").value));
    msg.textContent = "Done! Balance left: Rs " + left;
  } catch (error) {
    if (error instanceof ValidationError) {
      msg.textContent = "Input problem: " + error.message;
    } else if (error instanceof BalanceError) {
      msg.textContent = error.message;
    } else {
      throw error;   // unknown error: let it go up
    }
  }
});
</script>

</body>
</html>
Try it Yourself »

Try 0, 2000 and then 9000.

Only catch errors you know how to handle. If you catch an error and do nothing, a real bug becomes invisible. Re-throw anything you did not expect.

Error Cause

When you catch one error and throw a new, clearer one, pass the original as cause so no detail is lost:

Example

javascript
try {
  JSON.parse("{bad json}");
} catch (err) {
  const wrapped = new Error("Could not read saved settings", { cause: err });
  console.log(wrapped.message, "|", wrapped.cause.name);
}
Output
Could not read saved settings | SyntaxError

Exercise

Exercise

When does the code inside a finally block run?

Learn JavaScript with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp