Download Comfyui-Resolution-Master/js/ErrorHandler.js from MarkLilly/mis-custom-nodes: direct link, hf CLI and curl.
- Browser
- Download file 11 kB
-
https://huggingface.co/MarkLilly/mis-custom-nodes/resolve/main/Comfyui-Resolution-Master/js/ErrorHandler.js
- Command line
-
hf download hf://MarkLilly/mis-custom-nodes/Comfyui-Resolution-Master/js/ErrorHandler.js
-
curl -L -o ErrorHandler.js https://huggingface.co/MarkLilly/mis-custom-nodes/resolve/main/Comfyui-Resolution-Master/js/ErrorHandler.js
11 kB
| /** | |
| * ErrorHandler - Centralna obs艂uga b艂臋d贸w | |
| * Eliminuje powtarzalne wzorce obs艂ugi b艂臋d贸w w ca艂ym projekcie | |
| */ | |
| import { createModuleLogger } from "./utils/LoggerUtils.js"; | |
| const log = createModuleLogger('ErrorHandler'); | |
| /** | |
| * Typy b艂臋d贸w w aplikacji | |
| */ | |
| export const ErrorTypes = { | |
| VALIDATION: 'VALIDATION_ERROR', | |
| NETWORK: 'NETWORK_ERROR', | |
| FILE_IO: 'FILE_IO_ERROR', | |
| CANVAS: 'CANVAS_ERROR', | |
| IMAGE_PROCESSING: 'IMAGE_PROCESSING_ERROR', | |
| STATE_MANAGEMENT: 'STATE_MANAGEMENT_ERROR', | |
| USER_INPUT: 'USER_INPUT_ERROR', | |
| SYSTEM: 'SYSTEM_ERROR' | |
| }; | |
| /** | |
| * Klasa b艂臋du aplikacji z dodatkowymi informacjami | |
| */ | |
| export class AppError extends Error { | |
| constructor(message, type = ErrorTypes.SYSTEM, details = null, originalError = null) { | |
| super(message); | |
| this.name = 'AppError'; | |
| this.type = type; | |
| this.details = details; | |
| this.originalError = originalError; | |
| this.timestamp = new Date().toISOString(); | |
| if (Error.captureStackTrace) { | |
| Error.captureStackTrace(this, AppError); | |
| } | |
| } | |
| } | |
| /** | |
| * Handler b艂臋d贸w z automatycznym logowaniem i kategoryzacj膮 | |
| */ | |
| export class ErrorHandler { | |
| constructor() { | |
| this.errorCounts = new Map(); | |
| this.errorHistory = []; | |
| this.maxHistorySize = 100; | |
| } | |
| /** | |
| * Obs艂uguje b艂膮d z automatycznym logowaniem | |
| * @param {Error | AppError | string} error - B艂膮d do obs艂u偶enia | |
| * @param {string} context - Kontekst wyst膮pienia b艂臋du | |
| * @param {object} additionalInfo - Dodatkowe informacje | |
| * @returns {AppError} Znormalizowany b艂膮d | |
| */ | |
| handle(error, context = 'Unknown', additionalInfo = {}) { | |
| const normalizedError = this.normalizeError(error, context, additionalInfo); | |
| this.logError(normalizedError, context); | |
| this.recordError(normalizedError); | |
| this.incrementErrorCount(normalizedError.type); | |
| return normalizedError; | |
| } | |
| /** | |
| * Normalizuje b艂膮d do standardowego formatu | |
| * @param {Error | AppError | string} error - B艂膮d do znormalizowania | |
| * @param {string} context - Kontekst | |
| * @param {object} additionalInfo - Dodatkowe informacje | |
| * @returns {AppError} Znormalizowany b艂膮d | |
| */ | |
| normalizeError(error, context, additionalInfo) { | |
| if (error instanceof AppError) { | |
| return error; | |
| } | |
| if (error instanceof Error) { | |
| const type = this.categorizeError(error, context); | |
| return new AppError(error.message, type, { context, ...additionalInfo }, error); | |
| } | |
| if (typeof error === 'string') { | |
| return new AppError(error, ErrorTypes.SYSTEM, { context, ...additionalInfo }); | |
| } | |
| return new AppError('Unknown error occurred', ErrorTypes.SYSTEM, { context, originalError: error, ...additionalInfo }); | |
| } | |
| /** | |
| * Kategoryzuje b艂膮d na podstawie wiadomo艣ci i kontekstu | |
| * @param {Error} error - B艂膮d do skategoryzowania | |
| * @param {string} context - Kontekst | |
| * @returns {ErrorType} Typ b艂臋du | |
| */ | |
| categorizeError(error, context) { | |
| const message = error.message.toLowerCase(); | |
| if (message.includes('fetch') || message.includes('network') || | |
| message.includes('connection') || message.includes('timeout')) { | |
| return ErrorTypes.NETWORK; | |
| } | |
| if (message.includes('file') || message.includes('read') || | |
| message.includes('write') || message.includes('path')) { | |
| return ErrorTypes.FILE_IO; | |
| } | |
| if (message.includes('invalid') || message.includes('required') || | |
| message.includes('validation') || message.includes('format')) { | |
| return ErrorTypes.VALIDATION; | |
| } | |
| if (message.includes('image') || message.includes('canvas') || | |
| message.includes('blob') || message.includes('tensor')) { | |
| return ErrorTypes.IMAGE_PROCESSING; | |
| } | |
| if (message.includes('state') || message.includes('cache') || | |
| message.includes('storage')) { | |
| return ErrorTypes.STATE_MANAGEMENT; | |
| } | |
| if (context.toLowerCase().includes('canvas')) { | |
| return ErrorTypes.CANVAS; | |
| } | |
| return ErrorTypes.SYSTEM; | |
| } | |
| /** | |
| * Loguje b艂膮d z odpowiednim poziomem | |
| * @param {AppError} error - B艂膮d do zalogowania | |
| * @param {string} context - Kontekst | |
| */ | |
| logError(error, context) { | |
| const logMessage = `[${error.type}] ${error.message}`; | |
| const logDetails = { | |
| context, | |
| timestamp: error.timestamp, | |
| details: error.details, | |
| stack: error.stack | |
| }; | |
| switch (error.type) { | |
| case ErrorTypes.VALIDATION: | |
| case ErrorTypes.USER_INPUT: | |
| log.warn(logMessage, logDetails); | |
| break; | |
| case ErrorTypes.NETWORK: | |
| log.error(logMessage, logDetails); | |
| break; | |
| default: | |
| log.error(logMessage, logDetails); | |
| } | |
| } | |
| /** | |
| * Zapisuje b艂膮d w historii | |
| * @param {AppError} error - B艂膮d do zapisania | |
| */ | |
| recordError(error) { | |
| this.errorHistory.push({ | |
| timestamp: error.timestamp, | |
| type: error.type, | |
| message: error.message, | |
| context: error.details?.context | |
| }); | |
| if (this.errorHistory.length > this.maxHistorySize) { | |
| this.errorHistory.shift(); | |
| } | |
| } | |
| /** | |
| * Zwi臋ksza licznik b艂臋d贸w dla danego typu | |
| * @param {ErrorType} errorType - Typ b艂臋du | |
| */ | |
| incrementErrorCount(errorType) { | |
| const current = this.errorCounts.get(errorType) || 0; | |
| this.errorCounts.set(errorType, current + 1); | |
| } | |
| /** | |
| * Zwraca statystyki b艂臋d贸w | |
| * @returns {ErrorStats} Statystyki b艂臋d贸w | |
| */ | |
| getErrorStats() { | |
| const errorCountsObj = {}; | |
| for (const [key, value] of this.errorCounts.entries()) { | |
| errorCountsObj[key] = value; | |
| } | |
| return { | |
| totalErrors: this.errorHistory.length, | |
| errorCounts: errorCountsObj, | |
| recentErrors: this.errorHistory.slice(-10), | |
| errorsByType: this.groupErrorsByType() | |
| }; | |
| } | |
| /** | |
| * Grupuje b艂臋dy wed艂ug typu | |
| * @returns {{ [key: string]: ErrorHistoryEntry[] }} B艂臋dy pogrupowane wed艂ug typu | |
| */ | |
| groupErrorsByType() { | |
| const grouped = {}; | |
| this.errorHistory.forEach((error) => { | |
| if (!grouped[error.type]) { | |
| grouped[error.type] = []; | |
| } | |
| grouped[error.type].push(error); | |
| }); | |
| return grouped; | |
| } | |
| /** | |
| * Czy艣ci histori臋 b艂臋d贸w | |
| */ | |
| clearHistory() { | |
| this.errorHistory = []; | |
| this.errorCounts.clear(); | |
| log.info('Error history cleared'); | |
| } | |
| } | |
| const errorHandler = new ErrorHandler(); | |
| /** | |
| * Wrapper funkcji z automatyczn膮 obs艂ug膮 b艂臋d贸w | |
| * @param {Function} fn - Funkcja do opakowania | |
| * @param {string} context - Kontekst wykonania | |
| * @returns {Function} Opakowana funkcja | |
| */ | |
| export function withErrorHandling(fn, context) { | |
| return async function (...args) { | |
| try { | |
| return await fn.apply(this, args); | |
| } | |
| catch (error) { | |
| const handledError = errorHandler.handle(error, context, { | |
| functionName: fn.name, | |
| arguments: args.length | |
| }); | |
| throw handledError; | |
| } | |
| }; | |
| } | |
| /** | |
| * Decorator dla metod klasy z automatyczn膮 obs艂ug膮 b艂臋d贸w | |
| * @param {string} context - Kontekst wykonania | |
| */ | |
| export function handleErrors(context) { | |
| return function (target, propertyKey, descriptor) { | |
| const originalMethod = descriptor.value; | |
| descriptor.value = async function (...args) { | |
| try { | |
| return await originalMethod.apply(this, args); | |
| } | |
| catch (error) { | |
| const handledError = errorHandler.handle(error, `${context}.${propertyKey}`, { | |
| className: target.constructor.name, | |
| methodName: propertyKey, | |
| arguments: args.length | |
| }); | |
| throw handledError; | |
| } | |
| }; | |
| return descriptor; | |
| }; | |
| } | |
| /** | |
| * Funkcja pomocnicza do tworzenia b艂臋d贸w walidacji | |
| * @param {string} message - Wiadomo艣膰 b艂臋du | |
| * @param {object} details - Szczeg贸艂y walidacji | |
| * @returns {AppError} B艂膮d walidacji | |
| */ | |
| export function createValidationError(message, details = {}) { | |
| return new AppError(message, ErrorTypes.VALIDATION, details); | |
| } | |
| /** | |
| * Funkcja pomocnicza do tworzenia b艂臋d贸w sieciowych | |
| * @param {string} message - Wiadomo艣膰 b艂臋du | |
| * @param {object} details - Szczeg贸艂y sieci | |
| * @returns {AppError} B艂膮d sieciowy | |
| */ | |
| export function createNetworkError(message, details = {}) { | |
| return new AppError(message, ErrorTypes.NETWORK, details); | |
| } | |
| /** | |
| * Funkcja pomocnicza do tworzenia b艂臋d贸w plik贸w | |
| * @param {string} message - Wiadomo艣膰 b艂臋du | |
| * @param {object} details - Szczeg贸艂y pliku | |
| * @returns {AppError} B艂膮d pliku | |
| */ | |
| export function createFileError(message, details = {}) { | |
| return new AppError(message, ErrorTypes.FILE_IO, details); | |
| } | |
| /** | |
| * Funkcja pomocnicza do bezpiecznego wykonania operacji | |
| * @param {() => Promise<T>} operation - Operacja do wykonania | |
| * @param {T} fallbackValue - Warto艣膰 fallback w przypadku b艂臋du | |
| * @param {string} context - Kontekst operacji | |
| * @returns {Promise<T>} Wynik operacji lub warto艣膰 fallback | |
| */ | |
| export async function safeExecute(operation, fallbackValue, context = 'SafeExecute') { | |
| try { | |
| return await operation(); | |
| } | |
| catch (error) { | |
| errorHandler.handle(error, context); | |
| return fallbackValue; | |
| } | |
| } | |
| /** | |
| * Funkcja do retry operacji z exponential backoff | |
| * @param {() => Promise<T>} operation - Operacja do powt贸rzenia | |
| * @param {number} maxRetries - Maksymalna liczba pr贸b | |
| * @param {number} baseDelay - Podstawowe op贸藕nienie w ms | |
| * @param {string} context - Kontekst operacji | |
| * @returns {Promise<T>} Wynik operacji | |
| */ | |
| export async function retryWithBackoff(operation, maxRetries = 3, baseDelay = 1000, context = 'RetryOperation') { | |
| let lastError; | |
| for (let attempt = 0; attempt <= maxRetries; attempt++) { | |
| try { | |
| return await operation(); | |
| } | |
| catch (error) { | |
| lastError = error; | |
| if (attempt === maxRetries) { | |
| break; | |
| } | |
| const delay = baseDelay * Math.pow(2, attempt); | |
| log.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms`, { error: lastError.message, context }); | |
| await new Promise(resolve => setTimeout(resolve, delay)); | |
| } | |
| } | |
| throw errorHandler.handle(lastError, context, { attempts: maxRetries + 1 }); | |
| } | |
| export { errorHandler }; | |
| export default errorHandler; | |