Error Handling
14 min
throw raises an error, unwinding the call stack until a try/catch
catches it (or it crashes the program). Always throw an Error
object — new Error("message") — not a plain string, since Error
carries a .message, a .stack trace, and a type you can distinguish
from other errors. You can subclass Error (class ValidationError extends Error {}) to create your own error types, checkable with
instanceof inside a catch block.
function safeDivide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
}
try {
safeDivide(10, 0);
} catch (e) {
console.log(e.message);
// Cannot divide by zero
}
instanceof still works correctly on the custom ValidationError class -- that's what lets a catch block react differently to specific error types instead of treating every thrown value the same way.
Write `safeDivide(a, b)` — returns `a / b`, but throws `new Error("Cannot divide by zero")` if `b` is 0. Then write `tryDivide(a, b)` that calls `safeDivide` and returns the error's `.message` string if it throws, or the numeric result otherwise.
What does `class ValidationError extends Error {}` give you that a plain `throw "some string"` doesn't?
You can throw and catch real Error objects, and understand why a custom Error subclass beats throwing a plain string.