/** * EN: Base HTTP error class for structured error handling * VI: Class lỗi HTTP cơ sở để xử lý lỗi có cấu trúc */ export class HttpError extends Error { public readonly statusCode: number; public readonly errorCode: string; public readonly isOperational: boolean; public readonly details?: any; constructor( message: string, statusCode: number = 500, errorCode: string = 'INTERNAL_ERROR', isOperational: boolean = true, details?: any ) { super(message); this.name = this.constructor.name; this.statusCode = statusCode; this.errorCode = errorCode; this.isOperational = isOperational; this.details = details; // EN: Capture stack trace for debugging // VI: Capture stack trace để debug Error.captureStackTrace(this, this.constructor); } /** * EN: Convert error to API response format * VI: Chuyển lỗi thành định dạng response API */ toApiResponse() { return { success: false, error: { code: this.errorCode, message: this.message, ...(this.details && { details: this.details }), }, timestamp: new Date().toISOString(), }; } } /** * EN: 400 Bad Request Error * VI: Lỗi 400 Bad Request */ export class BadRequestError extends HttpError { constructor(message: string = 'Bad Request / Yêu cầu không hợp lệ', details?: any) { super(message, 400, 'BAD_REQUEST', true, details); } } /** * EN: 401 Unauthorized Error * VI: Lỗi 401 Unauthorized */ export class UnauthorizedError extends HttpError { constructor(message: string = 'Authentication required / Yêu cầu xác thực', details?: any) { super(message, 401, 'UNAUTHORIZED', true, details); } } /** * EN: 403 Forbidden Error * VI: Lỗi 403 Forbidden */ export class ForbiddenError extends HttpError { constructor(message: string = 'Access denied / Truy cập bị từ chối', details?: any) { super(message, 403, 'FORBIDDEN', true, details); } } /** * EN: 404 Not Found Error * VI: Lỗi 404 Not Found */ export class NotFoundError extends HttpError { constructor(resource: string = 'Resource / Tài nguyên', details?: any) { super(`${resource} not found / ${resource} không tìm thấy`, 404, 'NOT_FOUND', true, details); } } /** * EN: 409 Conflict Error * VI: Lỗi 409 Conflict */ export class ConflictError extends HttpError { constructor(message: string = 'Resource conflict / Xung đột tài nguyên', details?: any) { super(message, 409, 'CONFLICT', true, details); } } /** * EN: 422 Unprocessable Entity Error (for validation) * VI: Lỗi 422 Unprocessable Entity (cho validation) */ export class ValidationError extends HttpError { constructor(message: string = 'Validation failed / Validation thất bại', details?: any) { super(message, 422, 'VALIDATION_ERROR', true, details); } } /** * EN: 429 Too Many Requests Error * VI: Lỗi 429 Too Many Requests */ export class RateLimitError extends HttpError { constructor(message: string = 'Too many requests / Quá nhiều yêu cầu', details?: any) { super(message, 429, 'RATE_LIMIT_EXCEEDED', true, details); } } /** * EN: 500 Internal Server Error * VI: Lỗi 500 Internal Server Error */ export class InternalServerError extends HttpError { constructor(message: string = 'Internal server error / Lỗi máy chủ nội bộ', details?: any) { super(message, 500, 'INTERNAL_ERROR', false, details); } } /** * EN: 503 Service Unavailable Error * VI: Lỗi 503 Service Unavailable */ export class ServiceUnavailableError extends HttpError { constructor(message: string = 'Service temporarily unavailable / Dịch vụ tạm thời không khả dụng', details?: any) { super(message, 503, 'SERVICE_UNAVAILABLE', true, details); } } /** * EN: Database Error * VI: Lỗi Database */ export class DatabaseError extends HttpError { constructor(message: string = 'Database error / Lỗi database', details?: any) { super(message, 500, 'DATABASE_ERROR', false, details); } } /** * EN: External Service Error * VI: Lỗi External Service */ export class ExternalServiceError extends HttpError { constructor(service: string, message?: string, details?: any) { super( message || `External service error: ${service} / Lỗi dịch vụ bên ngoài: ${service}`, 502, 'EXTERNAL_SERVICE_ERROR', true, details ); } }