UNPKG

@dharshansr/gitgenius

Version:

AI-powered commit message generator with enhanced features

198 lines 6.5 kB
/** * Error tracking system with comprehensive error monitoring */ import { logger } from './Logger.js'; import { ConfigManager } from '../core/ConfigManager.js'; import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'fs'; import { join } from 'path'; import { homedir } from 'os'; export class ErrorTracker { constructor() { this.errors = new Map(); this.configManager = new ConfigManager(); const errorDir = join(homedir(), '.gitgenius', 'errors'); if (!existsSync(errorDir)) { mkdirSync(errorDir, { recursive: true }); } this.errorLogPath = join(errorDir, 'errors.json'); this.loadErrors(); } static getInstance() { if (!ErrorTracker.instance) { ErrorTracker.instance = new ErrorTracker(); } return ErrorTracker.instance; } /** * Load errors from persistent storage */ loadErrors() { try { if (existsSync(this.errorLogPath)) { const content = readFileSync(this.errorLogPath, 'utf-8'); const errorArray = JSON.parse(content); errorArray.forEach(error => { this.errors.set(error.id, error); }); } } catch (error) { logger.warn('ErrorTracker', 'Failed to load error history', { error }); } } /** * Save errors to persistent storage */ saveErrors() { try { const errorArray = Array.from(this.errors.values()); writeFileSync(this.errorLogPath, JSON.stringify(errorArray, null, 2)); } catch (error) { logger.warn('ErrorTracker', 'Failed to save error history', { error }); } } /** * Generate error ID from message and category */ generateErrorId(category, message) { const hash = Buffer.from(`${category}:${message}`).toString('base64').substring(0, 16); return hash; } /** * Track an error */ trackError(category, message, error, context) { const id = this.generateErrorId(category, message); logger.error(category, message, error, context); const existingError = this.errors.get(id); if (existingError) { existingError.occurrences++; existingError.timestamp = new Date().toISOString(); existingError.resolved = false; if (context) { existingError.context = context; } } else { const errorRecord = { id, timestamp: new Date().toISOString(), category, message, stack: error?.stack, context, resolved: false, occurrences: 1 }; this.errors.set(id, errorRecord); } this.saveErrors(); } /** * Mark error as resolved */ resolveError(errorId) { const error = this.errors.get(errorId); if (error) { error.resolved = true; this.saveErrors(); logger.info('ErrorTracker', `Error resolved: ${errorId}`); return true; } return false; } /** * Get all errors */ getAllErrors(includeResolved = false) { const errors = Array.from(this.errors.values()); return includeResolved ? errors : errors.filter(e => !e.resolved); } /** * Get errors by category */ getErrorsByCategory(category, includeResolved = false) { return this.getAllErrors(includeResolved).filter(e => e.category === category); } /** * Get recent errors */ getRecentErrors(count = 10, includeResolved = false) { return this.getAllErrors(includeResolved) .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) .slice(0, count); } /** * Get error statistics */ getErrorStats() { const allErrors = this.getAllErrors(true); const unresolvedErrors = allErrors.filter(e => !e.resolved); const errorsByCategory = {}; const errorsByDay = {}; const errorCounts = new Map(); allErrors.forEach(error => { // By category errorsByCategory[error.category] = (errorsByCategory[error.category] || 0) + 1; // By day const day = error.timestamp.split('T')[0]; errorsByDay[day] = (errorsByDay[day] || 0) + 1; // Count occurrences const current = errorCounts.get(error.message) || 0; errorCounts.set(error.message, current + error.occurrences); }); // Get most common errors const mostCommonErrors = Array.from(errorCounts.entries()) .map(([message, count]) => ({ message, count })) .sort((a, b) => b.count - a.count) .slice(0, 10); return { totalErrors: allErrors.length, unresolvedErrors: unresolvedErrors.length, errorsByCategory, errorsByDay, mostCommonErrors }; } /** * Clear resolved errors */ clearResolvedErrors() { const beforeCount = this.errors.size; const unresolvedErrors = Array.from(this.errors.values()).filter(e => !e.resolved); this.errors.clear(); unresolvedErrors.forEach(error => { this.errors.set(error.id, error); }); this.saveErrors(); const clearedCount = beforeCount - this.errors.size; logger.info('ErrorTracker', `Cleared ${clearedCount} resolved errors`); return clearedCount; } /** * Clear all errors */ clearAllErrors() { this.errors.clear(); this.saveErrors(); logger.info('ErrorTracker', 'All errors cleared'); } /** * Export errors to file */ exportErrors(filePath) { try { const errors = this.getAllErrors(true); writeFileSync(filePath, JSON.stringify(errors, null, 2)); logger.info('ErrorTracker', `Errors exported to ${filePath}`); } catch (error) { logger.error('ErrorTracker', `Failed to export errors: ${error}`); throw error; } } } // Export singleton instance export const errorTracker = ErrorTracker.getInstance(); //# sourceMappingURL=ErrorTracker.js.map