UNPKG

@casoon/auditmysite

Version:

Professional website analysis suite with robust accessibility testing, Core Web Vitals performance monitoring, SEO analysis, and content optimization insights. Features isolated browser contexts, retry mechanisms, and comprehensive API endpoints for profe

237 lines 8.89 kB
"use strict"; /** * 🚨 Standardized Error Handling * * Common error types and handling utilities for the audit system. * Provides consistent error categorization and recovery strategies. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorHandler = exports.ConfigurationError = exports.PermissionError = exports.TimeoutError = exports.ResourceError = exports.ValidationError = exports.ParsingError = exports.BrowserError = exports.NetworkError = exports.ErrorCategory = exports.AuditError = void 0; exports.withErrorHandling = withErrorHandling; /** * Base class for all audit-related errors */ class AuditError extends Error { constructor(message, code, category, recoverable = false, context) { super(message); this.name = this.constructor.name; this.code = code; this.category = category; this.recoverable = recoverable; this.context = context; // Maintains proper stack trace for where error was thrown Error.captureStackTrace(this, this.constructor); } } exports.AuditError = AuditError; /** * Error categories for better error handling */ var ErrorCategory; (function (ErrorCategory) { ErrorCategory["NETWORK"] = "NETWORK"; ErrorCategory["BROWSER"] = "BROWSER"; ErrorCategory["PARSING"] = "PARSING"; ErrorCategory["VALIDATION"] = "VALIDATION"; ErrorCategory["RESOURCE"] = "RESOURCE"; ErrorCategory["TIMEOUT"] = "TIMEOUT"; ErrorCategory["PERMISSION"] = "PERMISSION"; ErrorCategory["CONFIGURATION"] = "CONFIGURATION"; ErrorCategory["UNKNOWN"] = "UNKNOWN"; })(ErrorCategory || (exports.ErrorCategory = ErrorCategory = {})); /** * Network-related errors (connection, DNS, HTTP) */ class NetworkError extends AuditError { constructor(message, url, statusCode) { super(message, 'ERR_NETWORK', ErrorCategory.NETWORK, true, // Retryable { url, statusCode }); } } exports.NetworkError = NetworkError; /** * Browser/Playwright-related errors */ class BrowserError extends AuditError { constructor(message, browserType, recoverable = false) { super(message, 'ERR_BROWSER', ErrorCategory.BROWSER, recoverable, { browserType }); } } exports.BrowserError = BrowserError; /** * Sitemap/XML parsing errors */ class ParsingError extends AuditError { constructor(message, source) { super(message, 'ERR_PARSING', ErrorCategory.PARSING, false, { source }); } } exports.ParsingError = ParsingError; /** * Data validation errors */ class ValidationError extends AuditError { constructor(message, field, value) { super(message, 'ERR_VALIDATION', ErrorCategory.VALIDATION, false, { field, value }); } } exports.ValidationError = ValidationError; /** * System resource errors (memory, CPU, disk) */ class ResourceError extends AuditError { constructor(message, resourceType, limit) { super(message, 'ERR_RESOURCE', ErrorCategory.RESOURCE, false, { resourceType, limit }); } } exports.ResourceError = ResourceError; /** * Timeout errors */ class TimeoutError extends AuditError { constructor(message, operation, timeoutMs) { super(message, 'ERR_TIMEOUT', ErrorCategory.TIMEOUT, true, // Retryable { operation, timeoutMs }); } } exports.TimeoutError = TimeoutError; /** * Permission/access errors */ class PermissionError extends AuditError { constructor(message, resource) { super(message, 'ERR_PERMISSION', ErrorCategory.PERMISSION, false, { resource }); } } exports.PermissionError = PermissionError; /** * Configuration errors */ class ConfigurationError extends AuditError { constructor(message, configKey, providedValue) { super(message, 'ERR_CONFIGURATION', ErrorCategory.CONFIGURATION, false, { configKey, providedValue }); } } exports.ConfigurationError = ConfigurationError; /** * Error handler utility */ class ErrorHandler { /** * Categorize unknown errors into known types */ static categorize(error) { if (error instanceof AuditError) { return error; } const errorMessage = error instanceof Error ? error.message : String(error); const lowerMessage = errorMessage.toLowerCase(); // Network errors if (lowerMessage.includes('network') || lowerMessage.includes('econnrefused') || lowerMessage.includes('enotfound') || lowerMessage.includes('timeout') || lowerMessage.includes('fetch failed')) { return new NetworkError(errorMessage); } // Browser errors if (lowerMessage.includes('browser') || lowerMessage.includes('playwright') || lowerMessage.includes('page closed') || lowerMessage.includes('context') || lowerMessage.includes('target closed')) { return new BrowserError(errorMessage); } // Parsing errors if (lowerMessage.includes('parse') || lowerMessage.includes('xml') || lowerMessage.includes('json') || lowerMessage.includes('sitemap')) { return new ParsingError(errorMessage); } // Validation errors if (lowerMessage.includes('invalid') || lowerMessage.includes('validation') || lowerMessage.includes('required')) { return new ValidationError(errorMessage); } // Resource errors if (lowerMessage.includes('memory') || lowerMessage.includes('heap') || lowerMessage.includes('out of') || lowerMessage.includes('resource')) { return new ResourceError(errorMessage); } // Timeout errors if (lowerMessage.includes('timeout')) { return new TimeoutError(errorMessage); } // Permission errors if (lowerMessage.includes('permission') || lowerMessage.includes('eacces') || lowerMessage.includes('forbidden')) { return new PermissionError(errorMessage); } // Unknown error return new AuditError(errorMessage, 'ERR_UNKNOWN', ErrorCategory.UNKNOWN, false); } /** * Get user-friendly error message with recovery suggestions */ static getUserMessage(error) { const messages = { [ErrorCategory.NETWORK]: `Network error: ${error.message}. Please check your internet connection and try again.`, [ErrorCategory.BROWSER]: `Browser error: ${error.message}. The browser may have crashed or closed unexpectedly.`, [ErrorCategory.PARSING]: `Parsing error: ${error.message}. The sitemap or data format may be invalid.`, [ErrorCategory.VALIDATION]: `Validation error: ${error.message}. Please check your input parameters.`, [ErrorCategory.RESOURCE]: `Resource error: ${error.message}. The system may be running out of memory or resources.`, [ErrorCategory.TIMEOUT]: `Timeout error: ${error.message}. The operation took too long. Try increasing timeout or reducing load.`, [ErrorCategory.PERMISSION]: `Permission error: ${error.message}. Check file/folder permissions.`, [ErrorCategory.CONFIGURATION]: `Configuration error: ${error.message}. Please review your configuration settings.`, [ErrorCategory.UNKNOWN]: `Unexpected error: ${error.message}` }; return messages[error.category] || error.message; } /** * Determine if error should be retried */ static shouldRetry(error, attemptNumber, maxRetries) { if (attemptNumber >= maxRetries) { return false; } return error.recoverable; } /** * Calculate backoff delay for retries */ static getRetryDelay(attemptNumber, baseDelay = 1000) { // Exponential backoff: 1s, 2s, 4s, 8s, ... return Math.min(baseDelay * Math.pow(2, attemptNumber - 1), 30000); // Max 30s } } exports.ErrorHandler = ErrorHandler; /** * Async wrapper with automatic error categorization and retry logic */ async function withErrorHandling(operation, options = {}) { const { maxRetries = 3, baseDelay = 1000, onRetry } = options; let lastError; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await operation(); } catch (error) { lastError = ErrorHandler.categorize(error); if (!ErrorHandler.shouldRetry(lastError, attempt, maxRetries)) { throw lastError; } if (onRetry) { onRetry(lastError, attempt); } const delay = ErrorHandler.getRetryDelay(attempt, baseDelay); await new Promise(resolve => setTimeout(resolve, delay)); } } throw lastError; } //# sourceMappingURL=audit-errors.js.map