UNPKG

@puberty-labs/clits

Version:

CLiTS (Chrome Logging and Inspection Tool Suite) is a powerful Node.js library for automated Chrome browser testing, logging, and inspection. It provides a comprehensive suite of tools for monitoring network requests, console logs, DOM mutations, and more

136 lines (135 loc) 5.53 kB
import { createLogger, format, transports } from 'winston'; const logger = createLogger({ level: 'info', format: format.combine(format.timestamp(), format.json()), transports: [ new transports.Console({ format: format.combine(format.colorize(), format.simple()) }) ] }); export class ChromeErrorHandler { constructor(config = {}) { this.retryConfig = { ...ChromeErrorHandler.DEFAULT_RETRY_CONFIG, ...config }; } static isChromeError(error) { if (!error) return false; return Object.values(ChromeErrorHandler.KNOWN_ERRORS).some(({ pattern }) => pattern.test(error.message)); } static handleError(error) { if (!error) return null; for (const [, errorInfo] of Object.entries(ChromeErrorHandler.KNOWN_ERRORS)) { if (errorInfo.pattern.test(error.message)) { return { code: errorInfo.code, message: error.message, platform: process.platform, severity: errorInfo.severity, recoverable: errorInfo.recoverable, recommendation: errorInfo.recommendation }; } } return null; } static shouldSuppressError(error) { const errorInfo = ChromeErrorHandler.handleError(error); if (!errorInfo) return false; // Suppress all warning-level errors that are recoverable return errorInfo.severity === 'warning' && errorInfo.recoverable; } async executeWithRetry(operation, operationName) { let lastError = null; let delay = this.retryConfig.initialDelayMs; for (let attempt = 1; attempt <= this.retryConfig.maxRetries; attempt++) { try { return await operation(); } catch (error) { if (!(error instanceof Error)) throw error; lastError = error; const errorInfo = ChromeErrorHandler.handleError(error); if (!errorInfo?.recoverable) throw error; if (attempt < this.retryConfig.maxRetries) { logger.warn(`Attempt ${attempt} failed for ${operationName}: ${error.message}. Retrying in ${delay}ms...`); await new Promise(resolve => setTimeout(resolve, delay)); // Calculate next delay with exponential backoff delay = Math.min(delay * this.retryConfig.backoffFactor, this.retryConfig.maxDelayMs); } } } throw new Error(`Operation ${operationName} failed after ${this.retryConfig.maxRetries} attempts. Last error: ${lastError?.message}`); } } ChromeErrorHandler.DEFAULT_RETRY_CONFIG = { maxRetries: 3, initialDelayMs: 1000, maxDelayMs: 30000, backoffFactor: 2 }; ChromeErrorHandler.KNOWN_ERRORS = { DEPRECATED_ENDPOINT: { pattern: /Registration response error message: DEPRECATED_ENDPOINT/, code: 'DEPRECATED_ENDPOINT', severity: 'warning', recoverable: true, recommendation: 'This error can be safely ignored as it is handled automatically with retry logic.' }, CONNECTION_FAILED: { pattern: /Failed to connect to .* endpoint|Failed to connect to MCS endpoint/, code: 'CONNECTION_FAILED', severity: 'error', recoverable: true, recommendation: 'Check network connectivity and ensure Chrome is running with remote debugging enabled.' }, IMK_ERROR: { pattern: /_TIPropertyValueIsValid called with .* on nil context|Text input context does not respond to _valueForTIProperty/, code: 'IMK_ERROR', severity: 'warning', recoverable: true, recommendation: 'These are macOS-specific input method warnings that can be safely ignored.' }, TASK_POLICY: { pattern: /task_policy_set .* invalid argument/, code: 'TASK_POLICY', severity: 'warning', recoverable: true, recommendation: 'These are macOS-specific task policy warnings that can be safely ignored.' }, MEDIA_ACCESS: { pattern: /WebContentsDelegate::CheckMediaAccessPermission: Not supported/, code: 'MEDIA_ACCESS', severity: 'warning', recoverable: true, recommendation: 'This is a known limitation when running Chrome in debugging mode and can be safely ignored.' }, CSP_VIOLATION: { pattern: /Refused to frame .* because an ancestor violates the following Content Security Policy directive/, code: 'CSP_VIOLATION', severity: 'warning', recoverable: true, recommendation: 'Content Security Policy violations in debug mode can be safely ignored for internal testing.' }, TENSORFLOW_DELEGATE: { pattern: /Attempting to use a delegate that only supports static-sized tensors/, code: 'TENSORFLOW_DELEGATE', severity: 'warning', recoverable: true, recommendation: 'TensorFlow Lite delegate initialization warnings can be ignored in debug mode.' }, ALLOCATOR_WARNING: { pattern: /Trying to load the allocator multiple times/, code: 'ALLOCATOR_WARNING', severity: 'warning', recoverable: true, recommendation: 'Multiple allocator initialization attempts are expected in debug mode.' } };