UNPKG

dengun_ai-admin-client

Version:

Cliente simples para integração com o AI Admin Dashboard - Plug and Play

220 lines (219 loc) 7.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorReporter = void 0; const events_1 = require("events"); /** * Objetivo 4: Reportar erros, bugs e falhas da aplicação externa */ class ErrorReporter extends events_1.EventEmitter { constructor(config) { super(); this.connectionManager = null; this.errorQueue = []; this.reportInterval = null; this.isActive = false; this.errorStats = { totalErrors: 0, lastError: 0, errorsByType: new Map() }; this.config = config; this.setupGlobalErrorHandlers(); } /** * Iniciar serviço de relatório de erros */ async start(connectionManager) { if (connectionManager) { this.connectionManager = connectionManager; } this.isActive = true; this.startReportInterval(); this.emit('started'); } /** * Definir o gerenciador de conexão */ setConnectionManager(connectionManager) { this.connectionManager = connectionManager; } /** * Parar serviço de relatório de erros */ async stop() { this.isActive = false; this.stopReportInterval(); // Enviar erros restantes na fila if (this.errorQueue.length > 0) { await this.flushQueue(); } this.emit('stopped'); } /** * Reportar erro manualmente */ async reportError(error) { if (!this.isActive) return; // Adicionar à fila this.errorQueue.push(error); // Atualizar estatísticas this.updateStats(error); // Para erros críticos, enviar imediatamente if (this.isCriticalError(error)) { await this.flushQueue(); } this.emit('errorAdded', error); } /** * Reportar erro a partir de exception */ async reportException(exception, context) { const errorReport = { error: exception.message, errorCode: exception.name, stack: exception.stack, context: { ...context, type: 'exception' }, timestamp: Date.now() }; await this.reportError(errorReport); } /** * Reportar erro de aplicação */ async reportAppError(message, errorCode, context, sessionId, userId, tenantId) { const errorReport = { sessionId, userId, tenantId, error: message, errorCode, context: { ...context, type: 'application' }, timestamp: Date.now() }; await this.reportError(errorReport); } /** * Obter estatísticas de erros */ getErrorStats() { return { ...this.errorStats, errorsByType: Object.fromEntries(this.errorStats.errorsByType), pendingReports: this.errorQueue.length }; } /** * Obter erros pendentes na fila */ getPendingErrors() { return [...this.errorQueue]; } /** * Forçar envio dos erros na fila */ async forceFlush() { await this.flushQueue(); } // Métodos privados setupGlobalErrorHandlers() { if (typeof process !== 'undefined') { // Node.js error handlers process.on('uncaughtException', (error) => { this.reportException(error, { type: 'uncaughtException' }); }); process.on('unhandledRejection', (reason, promise) => { const error = reason instanceof Error ? reason : new Error(String(reason)); this.reportException(error, { type: 'unhandledRejection', promise: String(promise) }); }); } if (typeof window !== 'undefined') { // Browser error handlers window.addEventListener('error', (event) => { this.reportException(event.error || new Error(event.message), { type: 'windowError', filename: event.filename, lineno: event.lineno, colno: event.colno }); }); window.addEventListener('unhandledrejection', (event) => { const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason)); this.reportException(error, { type: 'unhandledRejection' }); }); } } startReportInterval() { var _a; this.stopReportInterval(); const interval = ((_a = this.config.options) === null || _a === void 0 ? void 0 : _a.reportInterval) || 30000; this.reportInterval = setInterval(async () => { await this.flushQueue(); }, interval); } stopReportInterval() { if (this.reportInterval) { clearInterval(this.reportInterval); this.reportInterval = null; } } async flushQueue() { var _a; if (this.errorQueue.length === 0) return; if (!((_a = this.connectionManager) === null || _a === void 0 ? void 0 : _a.isConnectionActive())) { this.emit('warning', 'Não conectado ao dashboard - erros mantidos na fila'); return; } const errorsToSend = [...this.errorQueue]; this.errorQueue = []; try { const response = await this.connectionManager.sendData('/api/bots/errors', { botId: this.config.botId, errors: errorsToSend }); if (response.success) { this.emit('errorsReported', errorsToSend); } else { // Recolocar na fila se falhou this.errorQueue.unshift(...errorsToSend); this.emit('error', new Error(response.error || 'Falha ao reportar erros')); } } catch (error) { // Recolocar na fila se deu erro this.errorQueue.unshift(...errorsToSend); this.emit('error', error); } } updateStats(error) { this.errorStats.totalErrors++; this.errorStats.lastError = error.timestamp; const errorType = error.errorCode || 'unknown'; const currentCount = this.errorStats.errorsByType.get(errorType) || 0; this.errorStats.errorsByType.set(errorType, currentCount + 1); } isCriticalError(error) { const criticalCodes = [ 'ECONNREFUSED', 'TIMEOUT', 'AUTH_FAILED', 'CRITICAL_ERROR', 'SECURITY_ERROR' ]; return criticalCodes.includes(error.errorCode || '') || error.error.toLowerCase().includes('critical') || error.error.toLowerCase().includes('fatal'); } } exports.ErrorReporter = ErrorReporter;