Error handling in JavaScript: try-catch, custom errors, and error types
try-catch-finally, Error types, ReferenceError TypeError SyntaxError, custom error classes, error.message error.stack, rethrowing errors, error boundaries pattern, handling async errors
Handling Errors Intentionally
Unhandled errors crash your program or silently corrupt state. Explicit error handling lets you recover gracefully, log failures, or provide meaningful messages to users. Understanding JavaScript's error types and how to create custom ones is essential for production code.
try-catch-finally
try {
const data = JSON.parse(userInput); // may throw SyntaxError
process(data);
} catch (err) {
if (err instanceof SyntaxError) {
console.error("Invalid JSON:", err.message);
} else {
throw err; // rethrow unexpected errors โ do not swallow them
}
} finally {
cleanup(); // always runs โ close connections, release locks
}
Built-In Error Types
JavaScript has several built-in error constructors: SyntaxError, TypeError, ReferenceError, RangeError, URIError. Use instanceof to distinguish them in catch blocks.
Custom Error Classes
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
try {
throw new ValidationError("email", "Must contain @");
} catch (err) {
if (err instanceof ValidationError) {
console.log(`Field ${err.field}: ${err.message}`);
} else {
throw err;
}
}
Golden Rule
Never silence errors with an empty catch block. Either handle the error meaningfully, log it with context, or rethrow it. Swallowed errors are the hardest bugs to diagnose in production โ they leave no trace of what went wrong or when.
