project migration to typescript

Project migration to typescript
This commit is contained in:
Dariusz L
2025-07-04 04:22:51 +02:00
parent 3e4cdf10bc
commit 5adc77471f
60 changed files with 12565 additions and 3021 deletions

View File

@@ -2,11 +2,8 @@
* 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";
import { createModuleLogger } from "./utils/LoggerUtils.js";
const log = createModuleLogger('ErrorHandler');
/**
* Typy błędów w aplikacji
*/
@@ -20,7 +17,6 @@ export const ErrorTypes = {
USER_INPUT: 'USER_INPUT_ERROR',
SYSTEM: 'SYSTEM_ERROR'
};
/**
* Klasa błędu aplikacji z dodatkowymi informacjami
*/
@@ -37,7 +33,6 @@ export class AppError extends Error {
}
}
}
/**
* Handler błędów z automatycznym logowaniem i kategoryzacją
*/
@@ -47,12 +42,11 @@ export class ErrorHandler {
this.errorHistory = [];
this.maxHistorySize = 100;
}
/**
* Obsługuje błąd z automatycznym logowaniem
* @param {Error|AppError} error - Błąd do obsłużenia
* @param {Error | AppError | string} error - Błąd do obsłużenia
* @param {string} context - Kontekst wystąpienia błędu
* @param {Object} additionalInfo - Dodatkowe informacje
* @param {object} additionalInfo - Dodatkowe informacje
* @returns {AppError} Znormalizowany błąd
*/
handle(error, context = 'Unknown', additionalInfo = {}) {
@@ -60,52 +54,33 @@ export class ErrorHandler {
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 {Error | AppError | string} error - Błąd do znormalizowania
* @param {string} context - Kontekst
* @param {Object} additionalInfo - Dodatkowe informacje
* @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
);
return new AppError(error.message, type, { context, ...additionalInfo }, error);
}
if (typeof error === 'string') {
return new AppError(
error,
ErrorTypes.SYSTEM,
{context, ...additionalInfo}
);
return new AppError(error, ErrorTypes.SYSTEM, { context, ...additionalInfo });
}
return new AppError(
'Unknown error occurred',
ErrorTypes.SYSTEM,
{context, originalError: error, ...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 {string} Typ błędu
* @returns {ErrorType} Typ błędu
*/
categorizeError(error, context) {
const message = error.message.toLowerCase();
@@ -132,10 +107,8 @@ export class ErrorHandler {
if (context.toLowerCase().includes('canvas')) {
return ErrorTypes.CANVAS;
}
return ErrorTypes.SYSTEM;
}
/**
* Loguje błąd z odpowiednim poziomem
* @param {AppError} error - Błąd do zalogowania
@@ -161,7 +134,6 @@ export class ErrorHandler {
log.error(logMessage, logDetails);
}
}
/**
* Zapisuje błąd w historii
* @param {AppError} error - Błąd do zapisania
@@ -177,36 +149,37 @@ export class ErrorHandler {
this.errorHistory.shift();
}
}
/**
* Zwiększa licznik błędów dla danego typu
* @param {string} errorType - Typ błędu
* @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 {Object} 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: Object.fromEntries(this.errorCounts),
errorCounts: errorCountsObj,
recentErrors: this.errorHistory.slice(-10),
errorsByType: this.groupErrorsByType()
};
}
/**
* Grupuje błędy według typu
* @returns {Object} Błędy pogrupowane według typu
* @returns {{ [key: string]: ErrorHistoryEntry[] }} Błędy pogrupowane według typu
*/
groupErrorsByType() {
const grouped = {};
this.errorHistory.forEach(error => {
this.errorHistory.forEach((error) => {
if (!grouped[error.type]) {
grouped[error.type] = [];
}
@@ -214,7 +187,6 @@ export class ErrorHandler {
});
return grouped;
}
/**
* Czyści historię błędów
*/
@@ -224,9 +196,7 @@ export class ErrorHandler {
log.info('Error history cleared');
}
}
const errorHandler = new ErrorHandler();
/**
* Wrapper funkcji z automatyczną obsługą błędów
* @param {Function} fn - Funkcja do opakowania
@@ -237,7 +207,8 @@ export function withErrorHandling(fn, context) {
return async function (...args) {
try {
return await fn.apply(this, args);
} catch (error) {
}
catch (error) {
const handledError = errorHandler.handle(error, context, {
functionName: fn.name,
arguments: args.length
@@ -246,7 +217,6 @@ export function withErrorHandling(fn, context) {
}
};
}
/**
* Decorator dla metod klasy z automatyczną obsługą błędów
* @param {string} context - Kontekst wykonania
@@ -254,11 +224,11 @@ export function withErrorHandling(fn, context) {
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) {
}
catch (error) {
const handledError = errorHandler.handle(error, `${context}.${propertyKey}`, {
className: target.constructor.name,
methodName: propertyKey,
@@ -267,86 +237,77 @@ export function handleErrors(context) {
throw handledError;
}
};
return descriptor;
};
}
/**
* Funkcja pomocnicza do tworzenia błędów walidacji
* @param {string} message - Wiadomość błędu
* @param {Object} details - Szczegóły walidacji
* @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
* @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
* @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 {Function} operation - Operacja do wykonania
* @param {*} fallbackValue - Wartość fallback w przypadku błędu
* @param {() => Promise<T>} operation - Operacja do wykonania
* @param {T} fallbackValue - Wartość fallback w przypadku błędu
* @param {string} context - Kontekst operacji
* @returns {*} Wynik operacji lub wartość fallback
* @returns {Promise<T>} Wynik operacji lub wartość fallback
*/
export async function safeExecute(operation, fallbackValue = null, context = 'SafeExecute') {
export async function safeExecute(operation, fallbackValue, context = 'SafeExecute') {
try {
return await operation();
} catch (error) {
}
catch (error) {
errorHandler.handle(error, context);
return fallbackValue;
}
}
/**
* Funkcja do retry operacji z exponential backoff
* @param {Function} operation - Operacja do powtórzenia
* @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 {*} Wynik 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) {
}
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: error.message, context});
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});
throw errorHandler.handle(lastError, context, { attempts: maxRetries + 1 });
}
export {errorHandler};
export { errorHandler };
export default errorHandler;