"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RateLimitError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.AuthenticationError = exports.ValidationError = exports.AppError = void 0; exports.globalErrorHandler = globalErrorHandler; class AppError extends Error { constructor(message, statusCode, code, isOperational = true) { super(message); this.statusCode = statusCode; this.code = code; this.isOperational = isOperational; this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } } exports.AppError = AppError; class ValidationError extends AppError { constructor(message, details) { super(message, 400, 'VALIDATION_ERROR'); this.details = details; } } exports.ValidationError = ValidationError; class AuthenticationError extends AppError { constructor(message = 'Unauthorized') { super(message, 401, 'AUTHENTICATION_ERROR'); } } exports.AuthenticationError = AuthenticationError; class ForbiddenError extends AppError { constructor(message = 'Forbidden') { super(message, 403, 'FORBIDDEN'); } } exports.ForbiddenError = ForbiddenError; class NotFoundError extends AppError { constructor(resource) { super(`${resource} not found`, 404, 'NOT_FOUND'); } } exports.NotFoundError = NotFoundError; class ConflictError extends AppError { constructor(message) { super(message, 409, 'CONFLICT'); } } exports.ConflictError = ConflictError; class RateLimitError extends AppError { constructor() { super('Too many requests', 429, 'RATE_LIMIT'); } } exports.RateLimitError = RateLimitError; function globalErrorHandler(err, req, res, _next) { const authReq = req; const logger = authReq.log; const userId = authReq.user?.id; if (err instanceof AppError && err.isOperational) { if (logger) { logger.warn({ err, statusCode: err.statusCode, userId }, err.message); } const body = { error: err.message, code: err.code }; if (err instanceof ValidationError && err.details !== undefined) { body['details'] = err.details; } res.status(err.statusCode).json(body); return; } if (logger) { logger.error({ err, userId }, 'Unhandled error'); } else { console.error('Unhandled error', err); } res.status(500).json({ error: process.env['NODE_ENV'] === 'production' ? 'Internal server error' : err.message, code: 'INTERNAL_ERROR', }); }