10. Error handling: try/catch, custom Error subclasses
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function validateAge(age) {
if (age < 0) throw new ValidationError("Age cannot be negative", "age");
return age;
}
try {
validateAge(-5);
} catch (err) {
if (err instanceof ValidationError) {
console.error(`Invalid ${err.field}: ${err.message}`);
} else {
throw err; // re-throw anything you didn't expect — never swallow silently
}
} finally {
console.log("validation attempted"); // always runs, even after a return/throw
}
Never write an empty catch {} — it hides real bugs. If you genuinely don't
care about an error, catch it and log it, so a silent failure is at least
discoverable in production logs.