@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +15 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,810 +1 @@
|
|
|
1
|
-
import { ERROR_TYPES, HTTP_STATUS, AGENT_STATUS } from '../utilities/constants.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Comprehensive error handling service for the Loxia AI Agents System
|
|
5
|
-
* Provides error classification, recovery strategies, and monitoring
|
|
6
|
-
*/
|
|
7
|
-
export class ErrorHandler {
|
|
8
|
-
constructor(config, logger) {
|
|
9
|
-
this.config = config || {};
|
|
10
|
-
this.logger = logger;
|
|
11
|
-
this.errorStats = {
|
|
12
|
-
totalErrors: 0,
|
|
13
|
-
errorsByType: new Map(),
|
|
14
|
-
errorsByAgent: new Map(),
|
|
15
|
-
recoveryAttempts: 0,
|
|
16
|
-
successfulRecoveries: 0,
|
|
17
|
-
criticalErrors: 0
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
this.recoveryStrategies = new Map();
|
|
21
|
-
this.errorSubscribers = new Set();
|
|
22
|
-
this.errorQueue = [];
|
|
23
|
-
this.isProcessingQueue = false;
|
|
24
|
-
|
|
25
|
-
this.initializeRecoveryStrategies();
|
|
26
|
-
this.setupErrorProcessing();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Handle an error with appropriate classification and recovery
|
|
31
|
-
* @param {Error|Object} error - Error object or error data
|
|
32
|
-
* @param {Object} context - Error context information
|
|
33
|
-
* @returns {Object} Error handling result
|
|
34
|
-
*/
|
|
35
|
-
async handleError(error, context = {}) {
|
|
36
|
-
try {
|
|
37
|
-
const errorInfo = this.classifyError(error, context);
|
|
38
|
-
const handlingResult = await this.processError(errorInfo);
|
|
39
|
-
|
|
40
|
-
this.updateErrorStats(errorInfo);
|
|
41
|
-
this.notifySubscribers(errorInfo, handlingResult);
|
|
42
|
-
|
|
43
|
-
return handlingResult;
|
|
44
|
-
|
|
45
|
-
} catch (handlingError) {
|
|
46
|
-
this.logger.error('Error handling failed', {
|
|
47
|
-
originalError: error.message,
|
|
48
|
-
handlingError: handlingError.message
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
error: handlingError,
|
|
54
|
-
recovery: null,
|
|
55
|
-
severity: 'critical'
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Classify error by type, severity, and context
|
|
62
|
-
* @param {Error|Object} error - Error to classify
|
|
63
|
-
* @param {Object} context - Error context
|
|
64
|
-
* @returns {Object} Classified error information
|
|
65
|
-
*/
|
|
66
|
-
classifyError(error, context = {}) {
|
|
67
|
-
const errorInfo = {
|
|
68
|
-
id: this.generateErrorId(),
|
|
69
|
-
timestamp: new Date().toISOString(),
|
|
70
|
-
message: error.message || error.toString(),
|
|
71
|
-
stack: error.stack || null,
|
|
72
|
-
code: error.code || null,
|
|
73
|
-
type: this.determineErrorType(error, context),
|
|
74
|
-
severity: this.determineSeverity(error, context),
|
|
75
|
-
context: { ...context },
|
|
76
|
-
recoverable: true,
|
|
77
|
-
retryCount: context.retryCount || 0,
|
|
78
|
-
maxRetries: this.getMaxRetries(error, context)
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// Additional classification based on context
|
|
82
|
-
if (context.agentId) {
|
|
83
|
-
errorInfo.agentId = context.agentId;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (context.toolId) {
|
|
87
|
-
errorInfo.toolId = context.toolId;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (context.operationId) {
|
|
91
|
-
errorInfo.operationId = context.operationId;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Determine if error is recoverable
|
|
95
|
-
errorInfo.recoverable = this.isRecoverable(errorInfo);
|
|
96
|
-
|
|
97
|
-
return errorInfo;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Process error with appropriate recovery strategy
|
|
102
|
-
* @param {Object} errorInfo - Classified error information
|
|
103
|
-
* @returns {Object} Processing result
|
|
104
|
-
*/
|
|
105
|
-
async processError(errorInfo) {
|
|
106
|
-
try {
|
|
107
|
-
this.logger.error('Processing error', {
|
|
108
|
-
errorId: errorInfo.id,
|
|
109
|
-
type: errorInfo.type,
|
|
110
|
-
severity: errorInfo.severity,
|
|
111
|
-
agentId: errorInfo.agentId,
|
|
112
|
-
message: errorInfo.message
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Check if this is a critical error requiring immediate attention
|
|
116
|
-
if (errorInfo.severity === 'critical') {
|
|
117
|
-
await this.handleCriticalError(errorInfo);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Attempt recovery if error is recoverable
|
|
121
|
-
let recoveryResult = null;
|
|
122
|
-
if (errorInfo.recoverable && errorInfo.retryCount < errorInfo.maxRetries) {
|
|
123
|
-
recoveryResult = await this.attemptRecovery(errorInfo);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Log error for monitoring and analysis
|
|
127
|
-
await this.logError(errorInfo, recoveryResult);
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
success: recoveryResult?.success || false,
|
|
131
|
-
errorId: errorInfo.id,
|
|
132
|
-
errorType: errorInfo.type,
|
|
133
|
-
severity: errorInfo.severity,
|
|
134
|
-
recovery: recoveryResult,
|
|
135
|
-
shouldRetry: this.shouldRetry(errorInfo, recoveryResult),
|
|
136
|
-
retryDelay: this.calculateRetryDelay(errorInfo)
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
} catch (processingError) {
|
|
140
|
-
this.logger.error('Error processing failed', {
|
|
141
|
-
errorId: errorInfo.id,
|
|
142
|
-
processingError: processingError.message
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
success: false,
|
|
147
|
-
errorId: errorInfo.id,
|
|
148
|
-
errorType: errorInfo.type,
|
|
149
|
-
severity: 'critical',
|
|
150
|
-
recovery: null,
|
|
151
|
-
shouldRetry: false
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Attempt to recover from an error using appropriate strategy
|
|
158
|
-
* @param {Object} errorInfo - Error information
|
|
159
|
-
* @returns {Object} Recovery result
|
|
160
|
-
*/
|
|
161
|
-
async attemptRecovery(errorInfo) {
|
|
162
|
-
try {
|
|
163
|
-
this.errorStats.recoveryAttempts++;
|
|
164
|
-
|
|
165
|
-
const strategy = this.recoveryStrategies.get(errorInfo.type) ||
|
|
166
|
-
this.recoveryStrategies.get('default');
|
|
167
|
-
|
|
168
|
-
if (!strategy) {
|
|
169
|
-
this.logger.warn('No recovery strategy found', { errorType: errorInfo.type });
|
|
170
|
-
return { success: false, reason: 'No recovery strategy available' };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
this.logger.info('Attempting error recovery', {
|
|
174
|
-
errorId: errorInfo.id,
|
|
175
|
-
errorType: errorInfo.type,
|
|
176
|
-
strategy: strategy.name,
|
|
177
|
-
retryCount: errorInfo.retryCount
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const recoveryResult = await strategy.recover(errorInfo);
|
|
181
|
-
|
|
182
|
-
if (recoveryResult.success) {
|
|
183
|
-
this.errorStats.successfulRecoveries++;
|
|
184
|
-
this.logger.info('Error recovery successful', {
|
|
185
|
-
errorId: errorInfo.id,
|
|
186
|
-
strategy: strategy.name
|
|
187
|
-
});
|
|
188
|
-
} else {
|
|
189
|
-
this.logger.warn('Error recovery failed', {
|
|
190
|
-
errorId: errorInfo.id,
|
|
191
|
-
strategy: strategy.name,
|
|
192
|
-
reason: recoveryResult.reason
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return recoveryResult;
|
|
197
|
-
|
|
198
|
-
} catch (recoveryError) {
|
|
199
|
-
this.logger.error('Recovery attempt failed', {
|
|
200
|
-
errorId: errorInfo.id,
|
|
201
|
-
recoveryError: recoveryError.message
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
success: false,
|
|
206
|
-
reason: `Recovery attempt failed: ${recoveryError.message}`
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Handle critical errors that require immediate attention
|
|
213
|
-
* @param {Object} errorInfo - Critical error information
|
|
214
|
-
*/
|
|
215
|
-
async handleCriticalError(errorInfo) {
|
|
216
|
-
try {
|
|
217
|
-
this.errorStats.criticalErrors++;
|
|
218
|
-
|
|
219
|
-
this.logger.error('Critical error detected', {
|
|
220
|
-
errorId: errorInfo.id,
|
|
221
|
-
message: errorInfo.message,
|
|
222
|
-
context: errorInfo.context
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// Emit critical error event
|
|
226
|
-
if (typeof process !== 'undefined' && process.emit) {
|
|
227
|
-
process.emit('criticalError', errorInfo);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Take immediate protective actions based on error type
|
|
231
|
-
switch (errorInfo.type) {
|
|
232
|
-
case ERROR_TYPES.AUTHENTICATION_FAILED:
|
|
233
|
-
await this.handleAuthenticationFailure(errorInfo);
|
|
234
|
-
break;
|
|
235
|
-
|
|
236
|
-
case ERROR_TYPES.RATE_LIMIT_EXCEEDED:
|
|
237
|
-
await this.handleRateLimitExceeded(errorInfo);
|
|
238
|
-
break;
|
|
239
|
-
|
|
240
|
-
case ERROR_TYPES.OPERATION_TIMEOUT:
|
|
241
|
-
await this.handleOperationTimeout(errorInfo);
|
|
242
|
-
break;
|
|
243
|
-
|
|
244
|
-
default:
|
|
245
|
-
await this.handleGenericCriticalError(errorInfo);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
} catch (criticalHandlingError) {
|
|
249
|
-
this.logger.error('Critical error handling failed', {
|
|
250
|
-
errorId: errorInfo.id,
|
|
251
|
-
handlingError: criticalHandlingError.message
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Determine error type based on error and context
|
|
258
|
-
* @param {Error|Object} error - Error object
|
|
259
|
-
* @param {Object} context - Error context
|
|
260
|
-
* @returns {string} Error type
|
|
261
|
-
*/
|
|
262
|
-
determineErrorType(error, context) {
|
|
263
|
-
// Check error code or HTTP status
|
|
264
|
-
if (error.code === 'ENOENT' || error.status === HTTP_STATUS.NOT_FOUND) {
|
|
265
|
-
return ERROR_TYPES.FILE_NOT_FOUND;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (error.code === 'EACCES' || error.status === HTTP_STATUS.FORBIDDEN) {
|
|
269
|
-
return ERROR_TYPES.PERMISSION_DENIED;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (error.status === HTTP_STATUS.UNAUTHORIZED) {
|
|
273
|
-
return ERROR_TYPES.AUTHENTICATION_FAILED;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (error.status === HTTP_STATUS.TOO_MANY_REQUESTS) {
|
|
277
|
-
return ERROR_TYPES.RATE_LIMIT_EXCEEDED;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Check error message patterns
|
|
281
|
-
const message = error.message?.toLowerCase() || '';
|
|
282
|
-
|
|
283
|
-
if (message.includes('timeout') || message.includes('timed out')) {
|
|
284
|
-
return ERROR_TYPES.OPERATION_TIMEOUT;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (message.includes('validation') || message.includes('invalid')) {
|
|
288
|
-
return ERROR_TYPES.VALIDATION_ERROR;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (message.includes('config') || message.includes('configuration')) {
|
|
292
|
-
return ERROR_TYPES.CONFIGURATION_ERROR;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Check context for additional clues
|
|
296
|
-
if (context.operation === 'file_operation') {
|
|
297
|
-
return ERROR_TYPES.FILE_NOT_FOUND;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (context.operation === 'api_request') {
|
|
301
|
-
return ERROR_TYPES.RATE_LIMIT_EXCEEDED;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return ERROR_TYPES.UNKNOWN_ERROR;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Determine error severity
|
|
309
|
-
* @param {Error|Object} error - Error object
|
|
310
|
-
* @param {Object} context - Error context
|
|
311
|
-
* @returns {string} Error severity
|
|
312
|
-
*/
|
|
313
|
-
determineSeverity(error, context) {
|
|
314
|
-
const criticalTypes = [
|
|
315
|
-
ERROR_TYPES.AUTHENTICATION_FAILED,
|
|
316
|
-
ERROR_TYPES.CONFIGURATION_ERROR
|
|
317
|
-
];
|
|
318
|
-
|
|
319
|
-
const highTypes = [
|
|
320
|
-
ERROR_TYPES.RATE_LIMIT_EXCEEDED,
|
|
321
|
-
ERROR_TYPES.OPERATION_TIMEOUT,
|
|
322
|
-
ERROR_TYPES.PERMISSION_DENIED
|
|
323
|
-
];
|
|
324
|
-
|
|
325
|
-
const errorType = this.determineErrorType(error, context);
|
|
326
|
-
|
|
327
|
-
if (criticalTypes.includes(errorType)) {
|
|
328
|
-
return 'critical';
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (highTypes.includes(errorType)) {
|
|
332
|
-
return 'high';
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Check retry count
|
|
336
|
-
const retryCount = (context && context.retryCount) || 0;
|
|
337
|
-
if (retryCount >= 3) {
|
|
338
|
-
return 'high';
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// Check if error is affecting agent operation
|
|
342
|
-
if (context && context.agentId && context.operation === 'agent_communication') {
|
|
343
|
-
return 'medium';
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return 'low';
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Check if error is recoverable
|
|
351
|
-
* @param {Object} errorInfo - Error information
|
|
352
|
-
* @returns {boolean} True if recoverable
|
|
353
|
-
*/
|
|
354
|
-
isRecoverable(errorInfo) {
|
|
355
|
-
const nonRecoverableTypes = [
|
|
356
|
-
ERROR_TYPES.AUTHENTICATION_FAILED,
|
|
357
|
-
ERROR_TYPES.CONFIGURATION_ERROR
|
|
358
|
-
];
|
|
359
|
-
|
|
360
|
-
if (nonRecoverableTypes.includes(errorInfo.type)) {
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// Not recoverable if max retries exceeded
|
|
365
|
-
if (errorInfo.retryCount >= errorInfo.maxRetries) {
|
|
366
|
-
return false;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Not recoverable if critical severity
|
|
370
|
-
if (errorInfo.severity === 'critical') {
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Get maximum retry attempts for error type
|
|
379
|
-
* @param {Error|Object} error - Error object
|
|
380
|
-
* @param {Object} context - Error context
|
|
381
|
-
* @returns {number} Maximum retries
|
|
382
|
-
*/
|
|
383
|
-
getMaxRetries(error, context) {
|
|
384
|
-
const errorType = this.determineErrorType(error, context);
|
|
385
|
-
|
|
386
|
-
const retryLimits = {
|
|
387
|
-
[ERROR_TYPES.RATE_LIMIT_EXCEEDED]: 5,
|
|
388
|
-
[ERROR_TYPES.OPERATION_TIMEOUT]: 3,
|
|
389
|
-
[ERROR_TYPES.FILE_NOT_FOUND]: 2,
|
|
390
|
-
[ERROR_TYPES.PERMISSION_DENIED]: 1,
|
|
391
|
-
[ERROR_TYPES.VALIDATION_ERROR]: 2,
|
|
392
|
-
[ERROR_TYPES.UNKNOWN_ERROR]: 3
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
return retryLimits[errorType] || 3;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Determine if error should be retried
|
|
400
|
-
* @param {Object} errorInfo - Error information
|
|
401
|
-
* @param {Object} recoveryResult - Recovery result
|
|
402
|
-
* @returns {boolean} True if should retry
|
|
403
|
-
*/
|
|
404
|
-
shouldRetry(errorInfo, recoveryResult) {
|
|
405
|
-
if (!errorInfo.recoverable) {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
if (errorInfo.retryCount >= errorInfo.maxRetries) {
|
|
410
|
-
return false;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
if (recoveryResult && recoveryResult.success) {
|
|
414
|
-
return false; // Recovery succeeded, no need to retry
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
return true;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* Calculate retry delay based on error information
|
|
422
|
-
* @param {Object} errorInfo - Error information
|
|
423
|
-
* @returns {number} Delay in milliseconds
|
|
424
|
-
*/
|
|
425
|
-
calculateRetryDelay(errorInfo) {
|
|
426
|
-
const baseDelay = 1000; // 1 second
|
|
427
|
-
const maxDelay = 30000; // 30 seconds
|
|
428
|
-
|
|
429
|
-
// Exponential backoff with jitter
|
|
430
|
-
const exponentialDelay = baseDelay * Math.pow(2, errorInfo.retryCount);
|
|
431
|
-
const jitter = Math.random() * 1000; // Random jitter up to 1 second
|
|
432
|
-
|
|
433
|
-
return Math.min(exponentialDelay + jitter, maxDelay);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Initialize recovery strategies for different error types
|
|
438
|
-
*/
|
|
439
|
-
initializeRecoveryStrategies() {
|
|
440
|
-
// File not found recovery
|
|
441
|
-
this.recoveryStrategies.set(ERROR_TYPES.FILE_NOT_FOUND, {
|
|
442
|
-
name: 'file_not_found_recovery',
|
|
443
|
-
recover: async (errorInfo) => {
|
|
444
|
-
if (errorInfo.context.filePath) {
|
|
445
|
-
// Try to check if file exists in different location
|
|
446
|
-
// or create directory structure if needed
|
|
447
|
-
return {
|
|
448
|
-
success: false,
|
|
449
|
-
reason: 'File recovery not implemented yet',
|
|
450
|
-
suggestion: 'Check file path and permissions'
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
return { success: false, reason: 'No file path provided' };
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
// Rate limit recovery
|
|
458
|
-
this.recoveryStrategies.set(ERROR_TYPES.RATE_LIMIT_EXCEEDED, {
|
|
459
|
-
name: 'rate_limit_recovery',
|
|
460
|
-
recover: async (errorInfo) => {
|
|
461
|
-
const waitTime = this.calculateRateLimitWait(errorInfo);
|
|
462
|
-
this.logger.info('Waiting for rate limit recovery', { waitTime });
|
|
463
|
-
|
|
464
|
-
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
465
|
-
|
|
466
|
-
return {
|
|
467
|
-
success: true,
|
|
468
|
-
action: 'waited_for_rate_limit',
|
|
469
|
-
waitTime
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
// Operation timeout recovery
|
|
475
|
-
this.recoveryStrategies.set(ERROR_TYPES.OPERATION_TIMEOUT, {
|
|
476
|
-
name: 'timeout_recovery',
|
|
477
|
-
recover: async (errorInfo) => {
|
|
478
|
-
// Try to increase timeout for next attempt
|
|
479
|
-
if (errorInfo.context.timeout) {
|
|
480
|
-
const newTimeout = Math.min(errorInfo.context.timeout * 1.5, 300000); // Max 5 minutes
|
|
481
|
-
return {
|
|
482
|
-
success: true,
|
|
483
|
-
action: 'increased_timeout',
|
|
484
|
-
newTimeout
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return { success: false, reason: 'Cannot adjust timeout' };
|
|
489
|
-
}
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
// Permission denied recovery
|
|
493
|
-
this.recoveryStrategies.set(ERROR_TYPES.PERMISSION_DENIED, {
|
|
494
|
-
name: 'permission_recovery',
|
|
495
|
-
recover: async (errorInfo) => {
|
|
496
|
-
return {
|
|
497
|
-
success: false,
|
|
498
|
-
reason: 'Permission errors require manual intervention',
|
|
499
|
-
suggestion: 'Check file/directory permissions'
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
// Validation error recovery
|
|
505
|
-
this.recoveryStrategies.set(ERROR_TYPES.VALIDATION_ERROR, {
|
|
506
|
-
name: 'validation_recovery',
|
|
507
|
-
recover: async (errorInfo) => {
|
|
508
|
-
// Try to clean/sanitize input data
|
|
509
|
-
if (errorInfo.context.inputData) {
|
|
510
|
-
return {
|
|
511
|
-
success: true,
|
|
512
|
-
action: 'data_sanitization',
|
|
513
|
-
suggestion: 'Input data was sanitized for retry'
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
return { success: false, reason: 'No input data to sanitize' };
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
// Default recovery strategy
|
|
522
|
-
this.recoveryStrategies.set('default', {
|
|
523
|
-
name: 'default_recovery',
|
|
524
|
-
recover: async (errorInfo) => {
|
|
525
|
-
// Generic recovery: wait and retry
|
|
526
|
-
const delay = this.calculateRetryDelay(errorInfo);
|
|
527
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
528
|
-
|
|
529
|
-
return {
|
|
530
|
-
success: true,
|
|
531
|
-
action: 'delay_retry',
|
|
532
|
-
delay
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Handle authentication failure
|
|
540
|
-
* @param {Object} errorInfo - Error information
|
|
541
|
-
*/
|
|
542
|
-
async handleAuthenticationFailure(errorInfo) {
|
|
543
|
-
this.logger.error('Authentication failure detected', { errorId: errorInfo.id });
|
|
544
|
-
|
|
545
|
-
// Could trigger token refresh, re-authentication, etc.
|
|
546
|
-
if (errorInfo.agentId) {
|
|
547
|
-
// Pause agent until authentication is resolved
|
|
548
|
-
// await this.orchestrator.pauseAgent(errorInfo.agentId, 300, 'Authentication failure');
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Handle rate limit exceeded
|
|
554
|
-
* @param {Object} errorInfo - Error information
|
|
555
|
-
*/
|
|
556
|
-
async handleRateLimitExceeded(errorInfo) {
|
|
557
|
-
const waitTime = this.calculateRateLimitWait(errorInfo);
|
|
558
|
-
|
|
559
|
-
this.logger.warn('Rate limit exceeded, implementing backoff', {
|
|
560
|
-
errorId: errorInfo.id,
|
|
561
|
-
waitTime,
|
|
562
|
-
agentId: errorInfo.agentId
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
if (errorInfo.agentId) {
|
|
566
|
-
// Pause agent temporarily
|
|
567
|
-
// await this.orchestrator.pauseAgent(errorInfo.agentId, waitTime / 1000, 'Rate limit exceeded');
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Handle operation timeout
|
|
573
|
-
* @param {Object} errorInfo - Error information
|
|
574
|
-
*/
|
|
575
|
-
async handleOperationTimeout(errorInfo) {
|
|
576
|
-
this.logger.error('Operation timeout detected', {
|
|
577
|
-
errorId: errorInfo.id,
|
|
578
|
-
operation: errorInfo.context.operation,
|
|
579
|
-
timeout: errorInfo.context.timeout
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
// Could cancel ongoing operations, adjust timeouts, etc.
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
* Handle generic critical error
|
|
587
|
-
* @param {Object} errorInfo - Error information
|
|
588
|
-
*/
|
|
589
|
-
async handleGenericCriticalError(errorInfo) {
|
|
590
|
-
this.logger.error('Generic critical error', {
|
|
591
|
-
errorId: errorInfo.id,
|
|
592
|
-
type: errorInfo.type,
|
|
593
|
-
message: errorInfo.message
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
// Generic protective measures
|
|
597
|
-
if (errorInfo.agentId) {
|
|
598
|
-
// Could pause agent for safety
|
|
599
|
-
this.logger.warn('Considering agent pause due to critical error', {
|
|
600
|
-
agentId: errorInfo.agentId
|
|
601
|
-
});
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
/**
|
|
606
|
-
* Calculate wait time for rate limit recovery
|
|
607
|
-
* @param {Object} errorInfo - Error information
|
|
608
|
-
* @returns {number} Wait time in milliseconds
|
|
609
|
-
*/
|
|
610
|
-
calculateRateLimitWait(errorInfo) {
|
|
611
|
-
const baseWait = 60000; // 1 minute
|
|
612
|
-
const retryMultiplier = Math.pow(2, errorInfo.retryCount);
|
|
613
|
-
const maxWait = 300000; // 5 minutes
|
|
614
|
-
|
|
615
|
-
return Math.min(baseWait * retryMultiplier, maxWait);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* Log error for monitoring and analysis
|
|
620
|
-
* @param {Object} errorInfo - Error information
|
|
621
|
-
* @param {Object} recoveryResult - Recovery result
|
|
622
|
-
*/
|
|
623
|
-
async logError(errorInfo, recoveryResult) {
|
|
624
|
-
try {
|
|
625
|
-
const logEntry = {
|
|
626
|
-
errorId: errorInfo.id,
|
|
627
|
-
timestamp: errorInfo.timestamp,
|
|
628
|
-
type: errorInfo.type,
|
|
629
|
-
severity: errorInfo.severity,
|
|
630
|
-
message: errorInfo.message,
|
|
631
|
-
agentId: errorInfo.agentId,
|
|
632
|
-
toolId: errorInfo.toolId,
|
|
633
|
-
operationId: errorInfo.operationId,
|
|
634
|
-
retryCount: errorInfo.retryCount,
|
|
635
|
-
recoveryAttempted: !!recoveryResult,
|
|
636
|
-
recoverySuccess: recoveryResult?.success || false,
|
|
637
|
-
recoveryAction: recoveryResult?.action || null
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
// Store in error queue for batch processing
|
|
641
|
-
this.errorQueue.push(logEntry);
|
|
642
|
-
|
|
643
|
-
// Process queue if not already processing
|
|
644
|
-
if (!this.isProcessingQueue) {
|
|
645
|
-
this.processErrorQueue();
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
} catch (loggingError) {
|
|
649
|
-
this.logger.error('Error logging failed', {
|
|
650
|
-
errorId: errorInfo.id,
|
|
651
|
-
loggingError: loggingError.message
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
* Process error queue for batch operations
|
|
658
|
-
*/
|
|
659
|
-
async processErrorQueue() {
|
|
660
|
-
if (this.isProcessingQueue || this.errorQueue.length === 0) {
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
this.isProcessingQueue = true;
|
|
665
|
-
|
|
666
|
-
try {
|
|
667
|
-
while (this.errorQueue.length > 0) {
|
|
668
|
-
const batch = this.errorQueue.splice(0, 10); // Process 10 at a time
|
|
669
|
-
|
|
670
|
-
// Here you would typically save to database, send to monitoring service, etc.
|
|
671
|
-
this.logger.debug('Processing error batch', { batchSize: batch.length });
|
|
672
|
-
|
|
673
|
-
// Simulate async processing
|
|
674
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
675
|
-
}
|
|
676
|
-
} catch (processingError) {
|
|
677
|
-
this.logger.error('Error queue processing failed', { error: processingError.message });
|
|
678
|
-
} finally {
|
|
679
|
-
this.isProcessingQueue = false;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Setup error processing infrastructure
|
|
685
|
-
*/
|
|
686
|
-
setupErrorProcessing() {
|
|
687
|
-
// Setup periodic queue processing
|
|
688
|
-
setInterval(() => {
|
|
689
|
-
if (this.errorQueue.length > 0) {
|
|
690
|
-
this.processErrorQueue();
|
|
691
|
-
}
|
|
692
|
-
}, 5000); // Process every 5 seconds
|
|
693
|
-
|
|
694
|
-
// Setup global error handlers
|
|
695
|
-
if (typeof process !== 'undefined') {
|
|
696
|
-
process.on('uncaughtException', (error) => {
|
|
697
|
-
this.handleError(error, {
|
|
698
|
-
type: 'uncaught_exception',
|
|
699
|
-
severity: 'critical'
|
|
700
|
-
});
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
704
|
-
this.handleError(new Error(`Unhandled Rejection: ${reason}`), {
|
|
705
|
-
type: 'unhandled_rejection',
|
|
706
|
-
severity: 'high',
|
|
707
|
-
promise: promise.toString()
|
|
708
|
-
});
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Update error statistics
|
|
715
|
-
* @param {Object} errorInfo - Error information
|
|
716
|
-
*/
|
|
717
|
-
updateErrorStats(errorInfo) {
|
|
718
|
-
this.errorStats.totalErrors++;
|
|
719
|
-
|
|
720
|
-
// Update error type statistics
|
|
721
|
-
if (!this.errorStats.errorsByType.has(errorInfo.type)) {
|
|
722
|
-
this.errorStats.errorsByType.set(errorInfo.type, 0);
|
|
723
|
-
}
|
|
724
|
-
this.errorStats.errorsByType.set(
|
|
725
|
-
errorInfo.type,
|
|
726
|
-
this.errorStats.errorsByType.get(errorInfo.type) + 1
|
|
727
|
-
);
|
|
728
|
-
|
|
729
|
-
// Update agent error statistics
|
|
730
|
-
if (errorInfo.agentId) {
|
|
731
|
-
if (!this.errorStats.errorsByAgent.has(errorInfo.agentId)) {
|
|
732
|
-
this.errorStats.errorsByAgent.set(errorInfo.agentId, 0);
|
|
733
|
-
}
|
|
734
|
-
this.errorStats.errorsByAgent.set(
|
|
735
|
-
errorInfo.agentId,
|
|
736
|
-
this.errorStats.errorsByAgent.get(errorInfo.agentId) + 1
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* Subscribe to error notifications
|
|
743
|
-
* @param {Function} callback - Callback function
|
|
744
|
-
*/
|
|
745
|
-
subscribe(callback) {
|
|
746
|
-
this.errorSubscribers.add(callback);
|
|
747
|
-
return () => this.errorSubscribers.delete(callback);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
/**
|
|
751
|
-
* Notify error subscribers
|
|
752
|
-
* @param {Object} errorInfo - Error information
|
|
753
|
-
* @param {Object} handlingResult - Handling result
|
|
754
|
-
*/
|
|
755
|
-
notifySubscribers(errorInfo, handlingResult) {
|
|
756
|
-
this.errorSubscribers.forEach(callback => {
|
|
757
|
-
try {
|
|
758
|
-
callback(errorInfo, handlingResult);
|
|
759
|
-
} catch (callbackError) {
|
|
760
|
-
this.logger.error('Error subscriber callback failed', {
|
|
761
|
-
error: callbackError.message
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
/**
|
|
768
|
-
* Generate unique error ID
|
|
769
|
-
* @returns {string} Error ID
|
|
770
|
-
*/
|
|
771
|
-
generateErrorId() {
|
|
772
|
-
return `err_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* Get error statistics
|
|
777
|
-
* @returns {Object} Error statistics
|
|
778
|
-
*/
|
|
779
|
-
getErrorStats() {
|
|
780
|
-
return {
|
|
781
|
-
totalErrors: this.errorStats.totalErrors,
|
|
782
|
-
errorsByType: Object.fromEntries(this.errorStats.errorsByType),
|
|
783
|
-
errorsByAgent: Object.fromEntries(this.errorStats.errorsByAgent),
|
|
784
|
-
recoveryAttempts: this.errorStats.recoveryAttempts,
|
|
785
|
-
successfulRecoveries: this.errorStats.successfulRecoveries,
|
|
786
|
-
recoverySuccessRate: this.errorStats.recoveryAttempts > 0
|
|
787
|
-
? this.errorStats.successfulRecoveries / this.errorStats.recoveryAttempts
|
|
788
|
-
: 0,
|
|
789
|
-
criticalErrors: this.errorStats.criticalErrors,
|
|
790
|
-
queueLength: this.errorQueue.length
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* Clear error statistics (for testing or reset)
|
|
796
|
-
*/
|
|
797
|
-
clearErrorStats() {
|
|
798
|
-
this.errorStats = {
|
|
799
|
-
totalErrors: 0,
|
|
800
|
-
errorsByType: new Map(),
|
|
801
|
-
errorsByAgent: new Map(),
|
|
802
|
-
recoveryAttempts: 0,
|
|
803
|
-
successfulRecoveries: 0,
|
|
804
|
-
criticalErrors: 0
|
|
805
|
-
};
|
|
806
|
-
this.errorQueue = [];
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
export default ErrorHandler;
|
|
1
|
+
function a0_0x1651(_0x4e4ed6,_0x398249){_0x4e4ed6=_0x4e4ed6-0x1c6;const _0x10bef7=a0_0x10be();let _0x165177=_0x10bef7[_0x4e4ed6];if(a0_0x1651['hMyRCD']===undefined){var _0x4d44ca=function(_0x4869a2){const _0x5189df='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5ace9e='',_0x4a702d='';for(let _0x49b217=0x0,_0x22e167,_0x50981d,_0xbea1c1=0x0;_0x50981d=_0x4869a2['charAt'](_0xbea1c1++);~_0x50981d&&(_0x22e167=_0x49b217%0x4?_0x22e167*0x40+_0x50981d:_0x50981d,_0x49b217++%0x4)?_0x5ace9e+=String['fromCharCode'](0xff&_0x22e167>>(-0x2*_0x49b217&0x6)):0x0){_0x50981d=_0x5189df['indexOf'](_0x50981d);}for(let _0x157593=0x0,_0x39f712=_0x5ace9e['length'];_0x157593<_0x39f712;_0x157593++){_0x4a702d+='%'+('00'+_0x5ace9e['charCodeAt'](_0x157593)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4a702d);};a0_0x1651['gnVUtx']=_0x4d44ca,a0_0x1651['uIiqvV']={},a0_0x1651['hMyRCD']=!![];}const _0x34d6f0=_0x10bef7[0x0],_0x2fcae2=_0x4e4ed6+_0x34d6f0,_0x5cca63=a0_0x1651['uIiqvV'][_0x2fcae2];return!_0x5cca63?(_0x165177=a0_0x1651['gnVUtx'](_0x165177),a0_0x1651['uIiqvV'][_0x2fcae2]=_0x165177):_0x165177=_0x5cca63,_0x165177;}function a0_0x10be(){const _0x3830bb=['BMfTzq','t3bLCMf0Aw9UihrPBwvVDxqGzgv0zwn0zwq','uhjVy2vZC2LUzYbLCNjVCIbIyxrJAa','CMf0zv9SAw1PDf9YzwnVDMvYEq','zxjYB3jZqNLbz2vUDa','AgfUzgXLr2vUzxjPy0nYAxrPy2fSrxjYB3i','B3bLCMf0Aw9U','Dw5KzwzPBMvK','q29UC2LKzxjPBMCGywDLBNqGCgf1C2uGzhvLihrVignYAxrPy2fSigvYCM9Y','Cg93','Dg9VBeLK','tM8GAw5WDxqGzgf0ysb0BYbZyw5PDgL6zq','C2v0','ntGXmZG0qLvUq0zj','tM8GCMvJB3zLCNKGC3rYyxrLz3KGyxzHAwXHyMXL','tM8GCMvJB3zLCNKGC3rYyxrLz3KGzM91BMq','zgvIDwC','Dg90ywXfCNjVCNm','vu5ltK9xtL9fuLjpuG','y29UzMLN','AgfUzgXLt3bLCMf0Aw9UvgLTzw91Da','AgfUzgXLqxv0AgvUDgLJyxrPB25gywLSDxjL','mJqXmdiYCKTMBejR','ChjVy2vZC0vYCM9YuxvLDwu','Dw5Oyw5KBgvKx3jLAMvJDgLVBG','zxjYB3i','BwvKAxvT','B3bLCMf0Aw9Uswq','uKfurv9msu1jvf9fwenfrurfra','qxv0AgvUDgLJyxrPB24GzMfPBhvYzsbKzxrLy3rLza','BgvUz3rO','vKfmsurbveLptL9fuLjpuG','mZqWmKLVBMP4sa','nNDlsLvODG','zgf0yv9Zyw5PDgL6yxrPB24','zxjYB3jtDwjZy3jPyMvYCW','y2fSy3vSyxrLuMf0zuXPBwL0v2fPDa','Dg9tDhjPBMC','y2XHC3nPzNLfCNjVCG','AgfZ','Aw5JCMvHC2vKx3rPBwvVDxq','Aw5JBhvKzxm','ywDLBNrjza','mti1odvLwuXtzK4','zgv0zxjTAw5Lu2v2zxjPDhK','zNjVBuvUDhjPzxm','BwvZC2fNzq','nJK5odC2mevbsvf6qW','Bg9NrxjYB3i','C2v0DxbfCNjVCLbYB2nLC3nPBMC','q09orKLhvvjbveLptL9fuLjpuG','C3rHDhvZ','sw5WDxqGzgf0ysb3yxmGC2fUAxrPEMvKigzVCIbYzxrYEq','CMv0CNLdB3vUDa','z2vUzxjHDgvfCNjVCKLK','DxbKyxrLrxjYB3jtDgf0CW','Aw5MBW','uevstuLtu0LptL9eru5jruq','zgvSzxrL','zgvSyxLFCMv0CNK','uMvJB3zLCNKGyxr0zw1WDcbMywLSzwq6ia','D2fYBG','zxjYB3jrDwv1zq','BM90Awz5u3vIC2nYAwjLCNm','odm3odiYmfLJyNntDG','AxnszwnVDMvYywjSzq','y2XLyxjfCNjVCLn0yxrZ','q3jPDgLJywWGzxjYB3iGzgv0zwn0zwq','mty5mtC5mLfVz2rbuW','t1bfuKfusu9ox1rjtuvpvvq','AgfUzgXLq3jPDgLJywXfCNjVCG','CMvJB3zLCNLbDhrLBxb0CW','ywrK','CMfUzg9T','ru5pru5u','rK9sqKLerevo','Dw5JyxvNAhrFzxHJzxb0Aw9U','DgLTzw91Da','ChjVy2vZC0vYCM9Y','y29UDgv4Da','DgLTzxn0yw1W','DhLWzq','y3jPDgLJywW','q2HLy2SGzMLSzs9KAxjLy3rVCNKGCgvYBwLZC2LVBNm','y29UzMLNDxjHDgLVBG','zxjYxW','Dw5JyxvNAhrfEgnLChrPB24','uhjVy2vZC2LUzYbLCNjVCG','zgv0zxjTAw5LrxjYB3juExbL','CMvJB3zLCNLtDhjHDgvNAwvZ','C3vIC2nYAwjL','rufdq0vt','y29Kzq','zMLSzv9UB3rFzM91BMrFCMvJB3zLCNK','qvvusevoveLdqvrjt05FrKfjteve','DMfSAwrHDgLVBL9YzwnVDMvYEq','AgLNAa','mJHMsuTVtwC','q2HLy2SGzMLSzsbWyxrOigfUzcbWzxjTAxnZAw9UCW','AxnqCM9JzxnZAw5NuxvLDwu','zxjYB3jtDgf0CW','BwLU','y2fSy3vSyxrLuMv0CNLezwXHEq','Bg9Nz2vY','z2v0','ywDLBNrFy29TBxvUAwnHDgLVBG','zMLSzvbHDgG','C3vJy2vZCW','Bwf4uMv0CMLLCW','DgLTzwqGB3v0','rKLmrv9ot1rFrK9vtKq','zxjYB3jZqNLuExbL','C2HVDwXKuMv0CNK','v2fPDgLUzYbMB3iGCMf0zsbSAw1PDcbYzwnVDMvYEq','y3jPDgLJywXfCNjVCG','rxjYB3iGChjVy2vZC2LUzYbMywLSzwq','nwLKrwfJAW','ntG4odmZm3vWu3nSvW','z2v0rxjYB3jtDgf0CW','rxjYB3iGCMvJB3zLCNKGC3vJy2vZC2z1Ba','C3vJy2vZC2z1BfjLy292zxjPzxm','yxr0zw1WDfjLy292zxj5','C2v2zxjPDhK','mZz2DMfdBum'];a0_0x10be=function(){return _0x3830bb;};return a0_0x10be();}const a0_0x55125b=a0_0x1651;(function(_0x47a5ba,_0x42bd7b){const _0x401b6a=a0_0x1651,_0x13537c=_0x47a5ba();while(!![]){try{const _0x1fc723=-parseInt(_0x401b6a(0x1c9))/0x1*(-parseInt(_0x401b6a(0x1e7))/0x2)+parseInt(_0x401b6a(0x1f2))/0x3*(-parseInt(_0x401b6a(0x215))/0x4)+-parseInt(_0x401b6a(0x1fc))/0x5*(-parseInt(_0x401b6a(0x1f1))/0x6)+parseInt(_0x401b6a(0x232))/0x7*(-parseInt(_0x401b6a(0x1de))/0x8)+parseInt(_0x401b6a(0x200))/0x9+parseInt(_0x401b6a(0x211))/0xa+-parseInt(_0x401b6a(0x1ca))/0xb*(parseInt(_0x401b6a(0x1d0))/0xc);if(_0x1fc723===_0x42bd7b)break;else _0x13537c['push'](_0x13537c['shift']());}catch(_0x2bac86){_0x13537c['push'](_0x13537c['shift']());}}}(a0_0x10be,0xdc603));import{ERROR_TYPES,HTTP_STATUS,AGENT_STATUS}from'../utilities/constants.js';export class ErrorHandler{constructor(_0x5ace9e,_0x4a702d){const _0x6c4376=a0_0x1651;this[_0x6c4376(0x1e4)]=_0x5ace9e||{},this['logger']=_0x4a702d,this['errorStats']={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this[_0x6c4376(0x22a)]=new Map(),this['errorSubscribers']=new Set(),this[_0x6c4376(0x20f)]=[],this[_0x6c4376(0x234)]=![],this['initializeRecoveryStrategies'](),this[_0x6c4376(0x202)]();}async['handleError'](_0x49b217,_0x22e167={}){const _0x31f185=a0_0x1651;try{const _0x50981d=this[_0x31f185(0x1f7)](_0x49b217,_0x22e167),_0xbea1c1=await this[_0x31f185(0x21f)](_0x50981d);return this[_0x31f185(0x208)](_0x50981d),this['notifySubscribers'](_0x50981d,_0xbea1c1),_0xbea1c1;}catch(_0x157593){return this[_0x31f185(0x238)][_0x31f185(0x1ea)]('Error\x20handling\x20failed',{'originalError':_0x49b217[_0x31f185(0x1ff)],'handlingError':_0x157593['message']}),{'success':![],'error':_0x157593,'recovery':null,'severity':'critical'};}}['classifyError'](_0x39f712,_0xbbc7e8={}){const _0x59d9c8=a0_0x1651,_0x5a15d8={'id':this['generateErrorId'](),'timestamp':new Date()['toISOString'](),'message':_0x39f712[_0x59d9c8(0x1ff)]||_0x39f712[_0x59d9c8(0x1f6)](),'stack':_0x39f712['stack']||null,'code':_0x39f712['code']||null,'type':this[_0x59d9c8(0x229)](_0x39f712,_0xbbc7e8),'severity':this[_0x59d9c8(0x1fd)](_0x39f712,_0xbbc7e8),'context':{..._0xbbc7e8},'recoverable':!![],'retryCount':_0xbbc7e8['retryCount']||0x0,'maxRetries':this['getMaxRetries'](_0x39f712,_0xbbc7e8)};return _0xbbc7e8['agentId']&&(_0x5a15d8['agentId']=_0xbbc7e8[_0x59d9c8(0x1fb)]),_0xbbc7e8['toolId']&&(_0x5a15d8['toolId']=_0xbbc7e8['toolId']),_0xbbc7e8['operationId']&&(_0x5a15d8['operationId']=_0xbbc7e8[_0x59d9c8(0x1ec)]),_0x5a15d8['recoverable']=this[_0x59d9c8(0x212)](_0x5a15d8),_0x5a15d8;}async['processError'](_0x16a272){const _0xd14a94=a0_0x1651;try{this['logger'][_0xd14a94(0x1ea)](_0xd14a94(0x228),{'errorId':_0x16a272['id'],'type':_0x16a272['type'],'severity':_0x16a272['severity'],'agentId':_0x16a272['agentId'],'message':_0x16a272[_0xd14a94(0x1ff)]});_0x16a272['severity']===_0xd14a94(0x223)&&await this['handleCriticalError'](_0x16a272);let _0x3c4ef9=null;return _0x16a272['recoverable']&&_0x16a272[_0xd14a94(0x206)]<_0x16a272['maxRetries']&&(_0x3c4ef9=await this[_0xd14a94(0x1ce)](_0x16a272)),await this[_0xd14a94(0x201)](_0x16a272,_0x3c4ef9),{'success':_0x3c4ef9?.[_0xd14a94(0x23c)]||![],'errorId':_0x16a272['id'],'errorType':_0x16a272[_0xd14a94(0x222)],'severity':_0x16a272[_0xd14a94(0x1cf)],'recovery':_0x3c4ef9,'shouldRetry':this[_0xd14a94(0x241)](_0x16a272,_0x3c4ef9),'retryDelay':this[_0xd14a94(0x237)](_0x16a272)};}catch(processingError){return this[_0xd14a94(0x238)][_0xd14a94(0x1ea)](_0xd14a94(0x1c8),{'errorId':_0x16a272['id'],'processingError':processingError['message']}),{'success':![],'errorId':_0x16a272['id'],'errorType':_0x16a272[_0xd14a94(0x222)],'severity':'critical','recovery':null,'shouldRetry':![]};}}async[a0_0x55125b(0x1ce)](_0x3b665e){const _0x4a3d74=a0_0x55125b;try{this[_0x4a3d74(0x235)][_0x4a3d74(0x218)]++;const _0x3bde8c=this[_0x4a3d74(0x22a)][_0x4a3d74(0x239)](_0x3b665e[_0x4a3d74(0x222)])||this[_0x4a3d74(0x22a)]['get']('default');if(!_0x3bde8c)return this[_0x4a3d74(0x238)]['warn'](_0x4a3d74(0x1e0),{'errorType':_0x3b665e['type']}),{'success':![],'reason':_0x4a3d74(0x1df)};this[_0x4a3d74(0x238)]['info']('Attempting\x20error\x20recovery',{'errorId':_0x3b665e['id'],'errorType':_0x3b665e['type'],'strategy':_0x3bde8c['name'],'retryCount':_0x3b665e[_0x4a3d74(0x206)]});const _0x2bd124=await _0x3bde8c['recover'](_0x3b665e);return _0x2bd124['success']?(this[_0x4a3d74(0x235)][_0x4a3d74(0x1cd)]++,this[_0x4a3d74(0x238)][_0x4a3d74(0x209)](_0x4a3d74(0x1cc),{'errorId':_0x3b665e['id'],'strategy':_0x3bde8c[_0x4a3d74(0x1d1)]})):this[_0x4a3d74(0x238)]['warn']('Error\x20recovery\x20failed',{'errorId':_0x3b665e['id'],'strategy':_0x3bde8c[_0x4a3d74(0x1d1)],'reason':_0x2bd124['reason']}),_0x2bd124;}catch(_0xa36480){return this[_0x4a3d74(0x238)]['error']('Recovery\x20attempt\x20failed',{'errorId':_0x3b665e['id'],'recoveryError':_0xa36480['message']}),{'success':![],'reason':_0x4a3d74(0x20d)+_0xa36480[_0x4a3d74(0x1ff)]};}}async[a0_0x55125b(0x217)](_0x290eca){const _0x2223b5=a0_0x55125b;try{this[_0x2223b5(0x235)]['criticalErrors']++,this[_0x2223b5(0x238)]['error'](_0x2223b5(0x214),{'errorId':_0x290eca['id'],'message':_0x290eca['message'],'context':_0x290eca['context']});typeof process!=='undefined'&&process['emit']&&process['emit'](_0x2223b5(0x1c7),_0x290eca);switch(_0x290eca['type']){case ERROR_TYPES['AUTHENTICATION_FAILED']:await this[_0x2223b5(0x1e6)](_0x290eca);break;case ERROR_TYPES[_0x2223b5(0x1ed)]:await this['handleRateLimitExceeded'](_0x290eca);break;case ERROR_TYPES[_0x2223b5(0x216)]:await this['handleOperationTimeout'](_0x290eca);break;default:await this[_0x2223b5(0x1d6)](_0x290eca);}}catch(_0x2aaa71){this['logger'][_0x2223b5(0x1ea)]('Critical\x20error\x20handling\x20failed',{'errorId':_0x290eca['id'],'handlingError':_0x2aaa71[_0x2223b5(0x1ff)]});}}[a0_0x55125b(0x229)](_0x33de1b,_0x2ff497){const _0x3dadb8=a0_0x55125b;if(_0x33de1b['code']===_0x3dadb8(0x21b)||_0x33de1b['status']===HTTP_STATUS['NOT_FOUND'])return ERROR_TYPES[_0x3dadb8(0x23f)];if(_0x33de1b[_0x3dadb8(0x22d)]===_0x3dadb8(0x22c)||_0x33de1b['status']===HTTP_STATUS[_0x3dadb8(0x21c)])return ERROR_TYPES['PERMISSION_DENIED'];if(_0x33de1b[_0x3dadb8(0x204)]===HTTP_STATUS['UNAUTHORIZED'])return ERROR_TYPES['AUTHENTICATION_FAILED'];if(_0x33de1b['status']===HTTP_STATUS['TOO_MANY_REQUESTS'])return ERROR_TYPES['RATE_LIMIT_EXCEEDED'];const _0x3d2532=_0x33de1b['message']?.['toLowerCase']()||'';if(_0x3d2532[_0x3dadb8(0x1fa)](_0x3dadb8(0x21e))||_0x3d2532[_0x3dadb8(0x1fa)](_0x3dadb8(0x23e)))return ERROR_TYPES['OPERATION_TIMEOUT'];if(_0x3d2532[_0x3dadb8(0x1fa)]('validation')||_0x3d2532[_0x3dadb8(0x1fa)]('invalid'))return ERROR_TYPES['VALIDATION_ERROR'];if(_0x3d2532[_0x3dadb8(0x1fa)]('config')||_0x3d2532['includes'](_0x3dadb8(0x225)))return ERROR_TYPES[_0x3dadb8(0x203)];if(_0x2ff497['operation']==='file_operation')return ERROR_TYPES['FILE_NOT_FOUND'];if(_0x2ff497[_0x3dadb8(0x1d7)]==='api_request')return ERROR_TYPES[_0x3dadb8(0x1ed)];return ERROR_TYPES['UNKNOWN_ERROR'];}['determineSeverity'](_0x76d6e9,_0x26edf5){const _0x34b711=a0_0x55125b,_0x4e78de=[ERROR_TYPES[_0x34b711(0x22f)],ERROR_TYPES[_0x34b711(0x203)]],_0x350fac=[ERROR_TYPES[_0x34b711(0x1ed)],ERROR_TYPES['OPERATION_TIMEOUT'],ERROR_TYPES['PERMISSION_DENIED']],_0x41b7b9=this[_0x34b711(0x229)](_0x76d6e9,_0x26edf5);if(_0x4e78de[_0x34b711(0x1fa)](_0x41b7b9))return'critical';if(_0x350fac['includes'](_0x41b7b9))return _0x34b711(0x231);const _0x10e561=_0x26edf5&&_0x26edf5[_0x34b711(0x206)]||0x0;if(_0x10e561>=0x3)return _0x34b711(0x231);if(_0x26edf5&&_0x26edf5['agentId']&&_0x26edf5['operation']===_0x34b711(0x23a))return _0x34b711(0x1eb);return'low';}['isRecoverable'](_0x33479c){const _0x13296d=a0_0x55125b,_0x4ca117=[ERROR_TYPES['AUTHENTICATION_FAILED'],ERROR_TYPES['CONFIGURATION_ERROR']];if(_0x4ca117['includes'](_0x33479c['type']))return![];if(_0x33479c[_0x13296d(0x206)]>=_0x33479c[_0x13296d(0x23d)])return![];if(_0x33479c[_0x13296d(0x1cf)]==='critical')return![];return!![];}['getMaxRetries'](_0x1e6d61,_0x3feec7){const _0x38a496=a0_0x55125b,_0x3f9ee8=this['determineErrorType'](_0x1e6d61,_0x3feec7),_0x279fd1={[ERROR_TYPES['RATE_LIMIT_EXCEEDED']]:0x5,[ERROR_TYPES[_0x38a496(0x216)]]:0x3,[ERROR_TYPES[_0x38a496(0x23f)]]:0x2,[ERROR_TYPES['PERMISSION_DENIED']]:0x1,[ERROR_TYPES[_0x38a496(0x1f0)]]:0x2,[ERROR_TYPES[_0x38a496(0x1e3)]]:0x3};return _0x279fd1[_0x3f9ee8]||0x3;}[a0_0x55125b(0x241)](_0x341fa9,_0x36ebbb){const _0x474d1e=a0_0x55125b;if(!_0x341fa9['recoverable'])return![];if(_0x341fa9[_0x474d1e(0x206)]>=_0x341fa9['maxRetries'])return![];if(_0x36ebbb&&_0x36ebbb[_0x474d1e(0x23c)])return![];return!![];}['calculateRetryDelay'](_0x329826){const _0x219677=a0_0x55125b,_0x3b5e65=0x3e8,_0x5a7544=0x7530,_0xaf8074=_0x3b5e65*Math[_0x219677(0x1da)](0x2,_0x329826['retryCount']),_0x3a9e0a=Math[_0x219677(0x21a)]()*0x3e8;return Math['min'](_0xaf8074+_0x3a9e0a,_0x5a7544);}['initializeRecoveryStrategies'](){const _0x49d959=a0_0x55125b;this['recoveryStrategies']['set'](ERROR_TYPES['FILE_NOT_FOUND'],{'name':_0x49d959(0x22e),'recover':async _0x3104f1=>{const _0x3c5975=_0x49d959;if(_0x3104f1[_0x3c5975(0x220)][_0x3c5975(0x23b)])return{'success':![],'reason':'File\x20recovery\x20not\x20implemented\x20yet','suggestion':_0x3c5975(0x233)};return{'success':![],'reason':'No\x20file\x20path\x20provided'};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)](ERROR_TYPES[_0x49d959(0x1ed)],{'name':_0x49d959(0x1d4),'recover':async _0x804db8=>{const _0x23ad3f=_0x49d959,_0xdb73b0=this['calculateRateLimitWait'](_0x804db8);return this['logger']['info'](_0x23ad3f(0x1c6),{'waitTime':_0xdb73b0}),await new Promise(_0x49c549=>setTimeout(_0x49c549,_0xdb73b0)),{'success':!![],'action':'waited_for_rate_limit','waitTime':_0xdb73b0};}}),this['recoveryStrategies']['set'](ERROR_TYPES[_0x49d959(0x216)],{'name':'timeout_recovery','recover':async _0x4a3f16=>{const _0x2a3f95=_0x49d959;if(_0x4a3f16[_0x2a3f95(0x220)]['timeout']){const _0x284c58=Math[_0x2a3f95(0x236)](_0x4a3f16[_0x2a3f95(0x220)][_0x2a3f95(0x21e)]*1.5,0x493e0);return{'success':!![],'action':_0x2a3f95(0x1f9),'newTimeout':_0x284c58};}return{'success':![],'reason':'Cannot\x20adjust\x20timeout'};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)](ERROR_TYPES[_0x49d959(0x20a)],{'name':'permission_recovery','recover':async _0x464dac=>{const _0x1a7092=_0x49d959;return{'success':![],'reason':'Permission\x20errors\x20require\x20manual\x20intervention','suggestion':_0x1a7092(0x224)};}}),this[_0x49d959(0x22a)]['set'](ERROR_TYPES['VALIDATION_ERROR'],{'name':_0x49d959(0x230),'recover':async _0x111961=>{const _0x356995=_0x49d959;if(_0x111961['context']['inputData'])return{'success':!![],'action':_0x356995(0x1f3),'suggestion':_0x356995(0x205)};return{'success':![],'reason':_0x356995(0x1dc)};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)]('default',{'name':'default_recovery','recover':async _0x158c31=>{const _0xcc4c57=_0x49d959,_0x366361=this[_0xcc4c57(0x237)](_0x158c31);return await new Promise(_0x26dd3b=>setTimeout(_0x26dd3b,_0x366361)),{'success':!![],'action':_0xcc4c57(0x20c),'delay':_0x366361};}});}async['handleAuthenticationFailure'](_0x10c06d){const _0x2f48d8=a0_0x55125b;this['logger'][_0x2f48d8(0x1ea)](_0x2f48d8(0x1ee),{'errorId':_0x10c06d['id']});if(_0x10c06d['agentId']){}}async['handleRateLimitExceeded'](_0x4908cc){const _0x52463d=a0_0x55125b,_0x51e84d=this[_0x52463d(0x1f5)](_0x4908cc);this[_0x52463d(0x238)][_0x52463d(0x20e)]('Rate\x20limit\x20exceeded,\x20implementing\x20backoff',{'errorId':_0x4908cc['id'],'waitTime':_0x51e84d,'agentId':_0x4908cc['agentId']});if(_0x4908cc[_0x52463d(0x1fb)]){}}async[a0_0x55125b(0x1e5)](_0x1bb8e6){const _0x5d7ae2=a0_0x55125b;this['logger']['error'](_0x5d7ae2(0x1d2),{'errorId':_0x1bb8e6['id'],'operation':_0x1bb8e6['context']['operation'],'timeout':_0x1bb8e6[_0x5d7ae2(0x220)][_0x5d7ae2(0x21e)]});}async[a0_0x55125b(0x1d6)](_0x183528){const _0x804f6f=a0_0x55125b;this[_0x804f6f(0x238)][_0x804f6f(0x1ea)]('Generic\x20critical\x20error',{'errorId':_0x183528['id'],'type':_0x183528[_0x804f6f(0x222)],'message':_0x183528['message']}),_0x183528[_0x804f6f(0x1fb)]&&this['logger'][_0x804f6f(0x20e)](_0x804f6f(0x1d9),{'agentId':_0x183528['agentId']});}['calculateRateLimitWait'](_0x57d402){const _0x2681e1=a0_0x55125b,_0xf62bed=0xea60,_0x8a9ef5=Math[_0x2681e1(0x1da)](0x2,_0x57d402[_0x2681e1(0x206)]),_0x4c9cd4=0x493e0;return Math[_0x2681e1(0x236)](_0xf62bed*_0x8a9ef5,_0x4c9cd4);}async[a0_0x55125b(0x201)](_0x580fd4,_0x5b2e8d){const _0x49c2cc=a0_0x55125b;try{const _0x3cc9d8={'errorId':_0x580fd4['id'],'timestamp':_0x580fd4[_0x49c2cc(0x221)],'type':_0x580fd4['type'],'severity':_0x580fd4[_0x49c2cc(0x1cf)],'message':_0x580fd4[_0x49c2cc(0x1ff)],'agentId':_0x580fd4[_0x49c2cc(0x1fb)],'toolId':_0x580fd4[_0x49c2cc(0x1db)],'operationId':_0x580fd4[_0x49c2cc(0x1ec)],'retryCount':_0x580fd4[_0x49c2cc(0x206)],'recoveryAttempted':!!_0x5b2e8d,'recoverySuccess':_0x5b2e8d?.[_0x49c2cc(0x23c)]||![],'recoveryAction':_0x5b2e8d?.['action']||null};this[_0x49c2cc(0x20f)]['push'](_0x3cc9d8),!this['isProcessingQueue']&&this[_0x49c2cc(0x1e8)]();}catch(_0x1fd31c){this['logger'][_0x49c2cc(0x1ea)]('Error\x20logging\x20failed',{'errorId':_0x580fd4['id'],'loggingError':_0x1fd31c['message']});}}async[a0_0x55125b(0x1e8)](){const _0x4a726b=a0_0x55125b;if(this[_0x4a726b(0x234)]||this[_0x4a726b(0x20f)]['length']===0x0)return;this[_0x4a726b(0x234)]=!![];try{while(this['errorQueue'][_0x4a726b(0x1ef)]>0x0){const _0xedd82c=this[_0x4a726b(0x20f)]['splice'](0x0,0xa);this[_0x4a726b(0x238)][_0x4a726b(0x1e1)](_0x4a726b(0x1d3),{'batchSize':_0xedd82c['length']}),await new Promise(_0x3d258f=>setTimeout(_0x3d258f,0x64));}}catch(processingError){this[_0x4a726b(0x238)]['error']('Error\x20queue\x20processing\x20failed',{'error':processingError['message']});}finally{this['isProcessingQueue']=![];}}['setupErrorProcessing'](){const _0x1630e7=a0_0x55125b;setInterval(()=>{const _0x1be9fd=a0_0x1651;this[_0x1be9fd(0x20f)]['length']>0x0&&this['processErrorQueue']();},0x1388),typeof process!==_0x1630e7(0x1d8)&&(process['on'](_0x1630e7(0x227),_0x36901d=>{const _0x1b45d2=_0x1630e7;this['handleError'](_0x36901d,{'type':_0x1b45d2(0x21d),'severity':'critical'});}),process['on']('unhandledRejection',(_0x185313,_0x2672bd)=>{const _0x4656d2=_0x1630e7;this['handleError'](new Error('Unhandled\x20Rejection:\x20'+_0x185313),{'type':_0x4656d2(0x1e9),'severity':'high','promise':_0x2672bd['toString']()});}));}['updateErrorStats'](_0x2d6e46){const _0x554b64=a0_0x55125b;this[_0x554b64(0x235)][_0x554b64(0x1e2)]++,!this[_0x554b64(0x235)]['errorsByType'][_0x554b64(0x1f8)](_0x2d6e46[_0x554b64(0x222)])&&this['errorStats'][_0x554b64(0x240)][_0x554b64(0x1dd)](_0x2d6e46[_0x554b64(0x222)],0x0),this['errorStats']['errorsByType'][_0x554b64(0x1dd)](_0x2d6e46['type'],this['errorStats'][_0x554b64(0x240)]['get'](_0x2d6e46['type'])+0x1),_0x2d6e46[_0x554b64(0x1fb)]&&(!this['errorStats']['errorsByAgent'][_0x554b64(0x1f8)](_0x2d6e46['agentId'])&&this[_0x554b64(0x235)][_0x554b64(0x1d5)][_0x554b64(0x1dd)](_0x2d6e46['agentId'],0x0),this['errorStats']['errorsByAgent'][_0x554b64(0x1dd)](_0x2d6e46[_0x554b64(0x1fb)],this['errorStats']['errorsByAgent']['get'](_0x2d6e46['agentId'])+0x1));}[a0_0x55125b(0x22b)](_0x581209){const _0x49cecd=a0_0x55125b;return this['errorSubscribers'][_0x49cecd(0x219)](_0x581209),()=>this['errorSubscribers'][_0x49cecd(0x20b)](_0x581209);}[a0_0x55125b(0x210)](_0x3f80cf,_0x23891b){const _0x5b9526=a0_0x55125b;this[_0x5b9526(0x1f4)]['forEach'](_0x57ebf0=>{try{_0x57ebf0(_0x3f80cf,_0x23891b);}catch(_0x771c24){this['logger']['error']('Error\x20subscriber\x20callback\x20failed',{'error':_0x771c24['message']});}});}[a0_0x55125b(0x207)](){const _0x4a8c04=a0_0x55125b;return _0x4a8c04(0x226)+Date['now']()+'_'+Math[_0x4a8c04(0x21a)]()[_0x4a8c04(0x1f6)](0x24)['substr'](0x2,0x9);}[a0_0x55125b(0x1cb)](){const _0x19ccc9=a0_0x55125b;return{'totalErrors':this['errorStats'][_0x19ccc9(0x1e2)],'errorsByType':Object[_0x19ccc9(0x1fe)](this[_0x19ccc9(0x235)]['errorsByType']),'errorsByAgent':Object[_0x19ccc9(0x1fe)](this['errorStats'][_0x19ccc9(0x1d5)]),'recoveryAttempts':this[_0x19ccc9(0x235)]['recoveryAttempts'],'successfulRecoveries':this[_0x19ccc9(0x235)][_0x19ccc9(0x1cd)],'recoverySuccessRate':this['errorStats'][_0x19ccc9(0x218)]>0x0?this[_0x19ccc9(0x235)][_0x19ccc9(0x1cd)]/this['errorStats'][_0x19ccc9(0x218)]:0x0,'criticalErrors':this[_0x19ccc9(0x235)]['criticalErrors'],'queueLength':this[_0x19ccc9(0x20f)][_0x19ccc9(0x1ef)]};}[a0_0x55125b(0x213)](){this['errorStats']={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this['errorQueue']=[];}}export default ErrorHandler;
|