Error Handling
try / catch / finally
try {
const data = JSON.parse("invalid json");
} catch (error) {
console.error(error.message); // "Unexpected token i in JSON..."
console.error(error.name); // "SyntaxError"
console.error(error.stack); // full stack trace
} finally {
console.log("always runs"); // cleanup code
}
Error Types
| Error Type | When |
|---|---|
SyntaxError | Invalid syntax |
ReferenceError | Variable not found |
TypeError | Wrong type operation |
RangeError | Value out of range |
URIError | Bad URI functions |
EvalError | Error in eval() |
Throwing Errors
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
}
// You can throw anything
throw "error string";
throw 404;
throw { message: "not found", code: 404 };
throw new TypeError("Expected a number");
Custom Errors
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
try {
throw new ValidationError("email", "Invalid email format");
} catch (error) {
if (error instanceof ValidationError) {
console.log(`${error.field}: ${error.message}`);
}
}
Async Error Handling
// Promise
fetch("/api")
.then((res) => res.json())
.catch((err) => console.error(err));
// Async/Await
async function getData() {
try {
const res = await fetch("/api");
return await res.json();
} catch (err) {
console.error("Request failed:", err);
}
}
// Global handlers
window.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled promise rejection:", event.reason);
});
Key Takeaways
- Always wrap risky code in
try/catch. - Create custom error classes for domain-specific errors.
- Use
finallyfor cleanup that must always run. - Handle async errors with
.catch()ortry/catchin async functions.