/** * Custom Application Error class for consistent error handling * Extends the built-in Error class with additional properties */ class AppError extends Error { /** * Create an application error * @param {string} message - Error message * @param {number} statusCode - HTTP status code * @param {boolean} isOperational - Whether the error is operational (expected) or programming error */ constructor(message, statusCode = 500, isOperational = true) { super(message); this.statusCode = statusCode; this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; this.isOperational = isOperational; // Capture stack trace Error.captureStackTrace(this, this.constructor); } } /** * Create a Bad Request error (400) */ class BadRequestError extends AppError { constructor(message = 'Bad Request') { super(message, 400); } } /** * Create an Unauthorized error (401) */ class UnauthorizedError extends AppError { constructor(message = 'Unauthorized') { super(message, 401); } } /** * Create a Forbidden error (403) */ class ForbiddenError extends AppError { constructor(message = 'Forbidden') { super(message, 403); } } /** * Create a Not Found error (404) */ class NotFoundError extends AppError { constructor(message = 'Resource not found') { super(message, 404); } } /** * Create a Conflict error (409) */ class ConflictError extends AppError { constructor(message = 'Resource conflict') { super(message, 409); } } /** * Create an Unprocessable Entity error (422) */ class ValidationError extends AppError { constructor(message = 'Validation failed', errors = null) { super(message, 422); this.errors = errors; } } /** * Create an Internal Server Error (500) */ class InternalServerError extends AppError { constructor(message = 'Internal server error') { super(message, 500, false); } } /** * Create a Database Error */ class DatabaseError extends AppError { constructor(message = 'Database error', originalError = null) { super(message, 500, false); this.originalError = originalError; } } module.exports = { AppError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, ValidationError, InternalServerError, DatabaseError };