UNPKG

@podx/core

Version:

🚀 Core utilities and shared functionality for PODx - Advanced Twitter/X scraping and crypto analysis toolkit

140 lines (137 loc) • 4.89 kB
// src/errors/index.ts function createError(type, message, context, originalError) { const statusCodes = { AUTHENTICATION: 401, AUTHORIZATION: 403, VALIDATION: 400, CONFIGURATION: 500, API: 502, FILESYSTEM: 500, NETWORK: 503, DATABASE: 500, RATE_LIMIT: 429, UNKNOWN: 500 }; const base = { type, message, statusCode: statusCodes[type] }; if (context !== undefined) { base.context = context; } if (originalError !== undefined) { base.originalError = originalError; } return base; } var ValidationError = (message, context) => createError("VALIDATION", message, context); var errors = { authentication: (message = "Authentication failed", context) => createError("AUTHENTICATION", message, context), authorization: (message = "Authorization failed", context) => createError("AUTHORIZATION", message, context), validation: (message = "Validation failed", context) => createError("VALIDATION", message, context), configuration: (message = "Configuration error", context) => createError("CONFIGURATION", message, context), api: (message = "API error", context) => createError("API", message, context), filesystem: (message = "File system error", context) => createError("FILESYSTEM", message, context), network: (message = "Network error", context) => createError("NETWORK", message, context), database: (message = "Database error", context) => createError("DATABASE", message, context), rateLimit: (message = "Rate limit exceeded", retryAfter, context) => { const base = createError("RATE_LIMIT", message, context); if (retryAfter !== undefined) base.retryAfter = retryAfter; return base; }, unknown: (message = "Unknown error occurred", originalError, context) => createError("UNKNOWN", message, context, originalError) }; class ErrorHandler { static async withErrorHandling(operation, context) { try { return await operation(); } catch (error) { if (this.isXServeError(error)) { throw error; } const wrappedError = createError("UNKNOWN", error instanceof Error ? error.message : "Unknown error occurred", { ...context, originalError: error }, error instanceof Error ? error : undefined); throw wrappedError; } } static async safeExecute(operation, context) { try { const data = await operation(); return { success: true, data }; } catch (error) { const xserveError = this.isXServeError(error) ? error : createError("UNKNOWN", error instanceof Error ? error.message : "Unknown error occurred", { ...context, originalError: error }, error instanceof Error ? error : undefined); return { success: false, error: xserveError }; } } static isRetryable(error) { if (this.isXServeError(error)) { return ["NETWORK", "API", "RATE_LIMIT"].includes(error.type); } const retryableMessages = [ "timeout", "network", "connection", "ECONNRESET", "ENOTFOUND", "ECONNREFUSED" ]; const message = error.message.toLowerCase(); return retryableMessages.some((pattern) => message.includes(pattern)); } static getUserMessage(error) { if (this.isXServeError(error)) { switch (error.type) { case "AUTHENTICATION": return "Authentication failed. Please check your credentials."; case "AUTHORIZATION": return "You do not have permission to perform this action."; case "VALIDATION": return "Invalid input provided. Please check your data."; case "RATE_LIMIT": return "Rate limit exceeded. Please try again later."; case "CONFIGURATION": return "Configuration error. Please check your settings."; case "NETWORK": return "Network error. Please check your connection."; default: return "An unexpected error occurred. Please try again."; } } return "An unexpected error occurred. Please try again."; } static isXServeError(error) { return error && typeof error === "object" && "type" in error && "message" in error; } } class RetryHandler { static async withRetry(operation, options = {}) { const { maxRetries = 3, baseDelay = 1000, maxDelay = 30000, shouldRetry = ErrorHandler.isRetryable } = options; let lastError; for (let attempt = 0;attempt <= maxRetries; attempt++) { try { return await operation(); } catch (error) { lastError = error; if (attempt === maxRetries || !shouldRetry(error)) { throw lastError; } const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay); await new Promise((resolve) => setTimeout(resolve, delay)); } } throw lastError; } } export { errors, createError, ValidationError, RetryHandler, ErrorHandler };