What are custom Error classes in JavaScript?
A custom error class extends the built-in Error to create your own meaningful error types.
How — extend Error, call super(message), and set a name so it's identifiable.
Why — distinguish error types in catch blocks (e.g. ValidationError vs NetworkError) and attach extra data.
Benefit: branch on the error type with instanceof instead of parsing error messages.
class AppError extends Error {
constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') {
super(message);
this.name = this.constructor.name;
this.statusCode = statusCode;
this.code = code;
}
}
class NotFoundError extends AppError {
constructor(resource) {
super(`${resource} not found`, 404, 'NOT_FOUND');
}
}
class ValidationError extends AppError {
constructor(errors) {
super('Validation failed', 400, 'VALIDATION_ERROR');
this.errors = errors; // Field-level errors
}
}
// Usage
function getUser(id) {
const user = db.find(id);
if (!user) throw new NotFoundError('User');
return user;
}
try {
const user = getUser(99);
} catch (err) {
if (err instanceof NotFoundError) {
console.log(err.statusCode); // 404
console.log(err.code); // 'NOT_FOUND'
} else if (err instanceof ValidationError) {
console.log(err.errors); // Field-level details
} else {
console.error('Unexpected:', err);
}
}AppError is the base with statusCode and code. NotFoundError and ValidationError provide domain-specific defaults. instanceof enables type-based error handling in catch blocks.
Custom errors carry structured data (statusCode, code, validation errors) for proper API responses.
Extend Error, set name to class name, pass message to super(). The instanceof-based catch handling shows proper error management.
Additional properties (statusCode, code) enable structured API error responses. This pattern is used in every production application.