JavaScript Error Handling
Handle errors gracefully and create robust applications.
Basic try/catch
try {
let data = JSON.parse(jsonString);
} catch (error) {
console.error("Parse error:", error.message);
} finally {
cleanup(); // Always runs
}
Throwing Errors
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
}
Error Types
Common built-in errors: TypeError, ReferenceError, RangeError, SyntaxError.
try {
let obj = null;
obj.foo.bar;
} catch (error) {
console.error(error.name); // "TypeError"
}
Custom Errors
Extend Error to add domain-specific context.
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
Form Validation Example
Collect all errors instead of stopping at the first one.
function validateForm(data) {
let errors = [];
try {
if (!data.email) throw new ValidationError("Email required", "email");
} catch (e) { errors.push(e); }
try {
if (data.password.length < 8)
throw new ValidationError("Password too short", "password");
} catch (e) { errors.push(e); }
return { valid: errors.length === 0, errors };
}
API Error Handler
Use static factory methods for common error types.
class ApiError extends Error {
constructor(status, message) {
super(message);
this.status = status;
}
static notFound(r) { return new ApiError(404, `${r} not found`); }
static unauthorized() { return new ApiError(401, "Unauthorized"); }
}
Error Boundary Pattern
Route different error types to specific handlers.
class ErrorBoundary {
#handlers = new Map();
catch(Type, handler) { this.#handlers.set(Type, handler); return this; }
handle(error) {
let handler = this.#handlers.get(error.constructor);
return handler ? handler(error) : (() => { throw error; })();
}
}
let boundary = new ErrorBoundary()
.catch(ValidationError, e => `Validation: ${e.field}`)
.catch(ApiError, e => `API ${e.status}: ${e.message}`);
Best Practices
- Use specific error types — Easier to handle
- Include context — What, where, why
- Use
finallyfor cleanup — Always runs - Don’t swallow errors — Log or re-throw
Common Mistakes
- Empty catch blocks — Silently hiding problems
- Throwing strings — Always throw
Errorobjects - Overusing try/catch — Only where needed
- Not providing context — Errors should be helpful