Skip to content

Error Handling

JavaScript handles runtime errors with try/catch/finally. Code that might throw goes in try; catch handles the thrown error; finally runs regardless of whether an error occurred. You can throw any value with throw, but throwing an Error object (or a subclass) is the convention, since it captures a stack trace.

try {
const result = JSON.parse("{ invalid json");
} catch (error) {
console.error("Failed to parse:", error.message);
} finally {
console.log("Cleanup always runs here");
}
function withdraw(balance, amount) {
if (amount > balance) {
throw new Error("Insufficient funds");
}
return balance - amount;
}
// Custom error types
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
try {
throw new ValidationError("Email is required");
} catch (error) {
if (error instanceof ValidationError) {
console.log("Validation issue:", error.message);
}
}

Not catching errors from async code with a plain try/catch around the wrong thing β€” a try/catch around a Promise-returning call without await won’t catch the rejection, since the function returns before the Promise settles.

// Doesn't catch the rejection -- fetchData() runs async, try/catch exits first
function loadData() {
try {
fetchData().then(data => process(data));
} catch (error) {
console.error(error); // never reached for a rejected Promise
}
}
// Correct -- either await inside an async function, or use .catch()
async function loadData() {
try {
const data = await fetchData();
process(data);
} catch (error) {
console.error(error); // correctly catches rejections
}
}
  1. When does the finally block execute?

    AnswerAlways β€” whether the try block succeeds, throws, or even returns early.
  2. Why doesn’t try { somePromise() } catch {} catch a Promise rejection?

    AnswerWithout await, the function call returns a pending Promise immediately, and the try block exits before the rejection happens β€” the error surfaces later, outside the try/catch.
  3. Why extend Error when creating a custom error type instead of throwing a plain object?

    AnswerError (and subclasses) automatically capture a stack trace and work correctly with instanceof checks and standard error-handling tooling.