@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
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 +14 -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_0x864e(_0x27d3ac,_0x3e7b4f){_0x27d3ac=_0x27d3ac-0x1c0;const _0x2122c6=a0_0x2122();let _0x864e35=_0x2122c6[_0x27d3ac];if(a0_0x864e['vOvxmG']===undefined){var _0x5f1dd2=function(_0x2b370b){const _0x4ac772='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x34d828='',_0x453d74='';for(let _0x2b8f95=0x0,_0x5bb5bf,_0x479737,_0x381d23=0x0;_0x479737=_0x2b370b['charAt'](_0x381d23++);~_0x479737&&(_0x5bb5bf=_0x2b8f95%0x4?_0x5bb5bf*0x40+_0x479737:_0x479737,_0x2b8f95++%0x4)?_0x34d828+=String['fromCharCode'](0xff&_0x5bb5bf>>(-0x2*_0x2b8f95&0x6)):0x0){_0x479737=_0x4ac772['indexOf'](_0x479737);}for(let _0x30f61f=0x0,_0xffe26f=_0x34d828['length'];_0x30f61f<_0xffe26f;_0x30f61f++){_0x453d74+='%'+('00'+_0x34d828['charCodeAt'](_0x30f61f)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x453d74);};a0_0x864e['uhmsEg']=_0x5f1dd2,a0_0x864e['mzndIj']={},a0_0x864e['vOvxmG']=!![];}const _0x568495=_0x2122c6[0x0],_0x170ed3=_0x27d3ac+_0x568495,_0x2e6a6c=a0_0x864e['mzndIj'][_0x170ed3];return!_0x2e6a6c?(_0x864e35=a0_0x864e['uhmsEg'](_0x864e35),a0_0x864e['mzndIj'][_0x170ed3]=_0x864e35):_0x864e35=_0x2e6a6c,_0x864e35;}function a0_0x2122(){const _0x171f81=['zxjYB3jZqNLuExbL','Aw5MBW','zMLSzvbHDgG','Aw5JBhvKzxm','Dg9VBeLK','AgfUzgXLrxjYB3i','Aw5PDgLHBgL6zvjLy292zxj5u3rYyxrLz2LLCW','zw1PDa','z2v0','y3jPDgLJywXfCNjVCNm','AgfZ','Bg93','AgfUzgXLr2vUzxjPy0nYAxrPy2fSrxjYB3i','vu5ltK9xtL9fuLjpuG','B3bLCMf0Aw9Uswq','tM8GzMLSzsbWyxrOihbYB3zPzgvK','y29Kzq','rufdq0vt','AgLNAa','Dg90ywXfCNjVCNm','t1bfuKfusu9ox1rjtuvpvvq','BMfTzq','BM90Awz5u3vIC2nYAwjLCNm','rKLmrv9ot1rFrK9vtKq','Bg9Nz2vY','vKfmsurbveLptL9fuLjpuG','uhjVy2vZC2LUzYbLCNjVCIbIyxrJAa','C3rHDhvZ','mtm5nJe4nxzzALHjua','CMvJB3zLCNLbDhrLBxb0CW','DgLTzw91Da','r2vUzxjPyYbJCML0AwnHBcbLCNjVCG','Bg9NrxjYB3i','ChjVy2vZC0vYCM9Y','rK9sqKLerevo','DMfSAwrHDgLVBL9YzwnVDMvYEq','rMLSzsbYzwnVDMvYEsbUB3qGAw1WBgvTzw50zwqGEwv0','mtyZmZGYngLtzwjoBG','mti4nZG0CKfkuwP4','zxjYB3i','Dw5Oyw5KBgvKx3jLAMvJDgLVBG','sw5WDxqGzgf0ysb3yxmGC2fUAxrPEMvKigzVCIbYzxrYEq','AxnszwnVDMvYywjSzq','Aw5WDxreyxrH','AgfUzgXLuMf0zuXPBwL0rxHJzwvKzwq','Dg9tDhjPBMC','C2v0DxbfCNjVCLbYB2nLC3nPBMC','C2HVDwXKuMv0CNK','zNjVBuvUDhjPzxm','rxjYB3iGAgfUzgXPBMCGzMfPBgvK','DxbKyxrLrxjYB3jtDgf0CW','rxjYB3iGBg9Nz2LUzYbMywLSzwq','Dw5Oyw5KBgvKuMvQzwn0Aw9U','zxjYB3jZqNLbz2vUDa','CMvJB3zLCMfIBgu','DgLTzwqGB3v0','mta4otC0mvnOAg1XqG','mta5mJC2wNDSvw9y','uhjVy2vZC2LUzYbLCNjVCG','CMvHC29U','tM8GCMvJB3zLCNKGC3rYyxrLz3KGzM91BMq','uMf0zsbSAw1PDcbLEgnLzwrLzcWGAw1WBgvTzw50Aw5NigjHy2TVzMy','zxjYB3jrDwv1zq','y2XHC3nPzNLfCNjVCG','q2fUBM90igfKANvZDcb0Aw1LB3v0','uKfurv9msu1jvf9fwenfrurfra','Cg93','AgfUzgXLt3bLCMf0Aw9UvgLTzw91Da','AgfUzgXLq3jPDgLJywXfCNjVCG','y2XLyxjfCNjVCLn0yxrZ','ywDLBNrjza','D2fPDgvKx2zVCL9YyxrLx2XPBwL0','DhLWzq','mtq3ntG0rhPmtM9T','CMvJB3zLCNLtDhjHDgvNAwvZ','qvvusevoveLdqvrjt05FrKfjteve','zgf0yv9Zyw5PDgL6yxrPB24','zxjYB3jtDwjZy3jPyMvYCW','CMv0CNLdB3vUDa','D2fYBG','uevstuLtu0LptL9eru5jruq','zM9YrwfJAa','zgvSzxrL','zMLSzv9UB3rFzM91BMrFCMvJB3zLCNK','ugvYBwLZC2LVBIbLCNjVCNmGCMvXDwLYzsbTyw51ywWGAw50zxj2zw50Aw9U','C3vJy2vZCW','CMfUzg9T','AxnqCM9JzxnZAw5NuxvLDwu','BwvZC2fNzq','CgvYBwLZC2LVBL9YzwnVDMvYEq','C2v2zxjPDhK','uMvJB3zLCNKGyxr0zw1WDcbMywLSzwq6ia','q3jPDgLJywWGzxjYB3iGAgfUzgXPBMCGzMfPBgvK','y29UDgv4Da','ru5pru5u','z2v0twf4uMv0CMLLCW','B3bLCMf0Aw9U','rxjYB3iGCMvJB3zLCNKGzMfPBgvK','DgLTzxn0yw1W','q09orKLhvvjbveLptL9fuLjpuG','y2fSy3vSyxrLuMv0CNLezwXHEq','zgv0zxjTAw5LrxjYB3juExbL','yxr0zw1WDfjLy292zxj5','Aw52ywXPza','C2v0','ywrK','CMvJB3zLCG','zMLSzv9VCgvYyxrPB24','BgvUz3rO','qxr0zw1WDgLUzYbLCNjVCIbYzwnVDMvYEq','n2vkvwTUBa','y3jPDgLJywW','Dw5KzwzPBMvK','zxjYB3jtDgf0CW','mJeXotyYA3nLtvrN','AgfUzgXLqxv0AgvUDgLJyxrPB25gywLSDxjL','q3jPDgLJywWGzxjYB3iGzgv0zwn0zwq'];a0_0x2122=function(){return _0x171f81;};return a0_0x2122();}const a0_0x25c7e4=a0_0x864e;(function(_0x45e8d8,_0x127c65){const _0x580c3c=a0_0x864e,_0x2b7b31=_0x45e8d8();while(!![]){try{const _0x5638c0=-parseInt(_0x580c3c(0x213))/0x1+parseInt(_0x580c3c(0x1da))/0x2+parseInt(_0x580c3c(0x1d9))/0x3+parseInt(_0x580c3c(0x1c7))/0x4+parseInt(_0x580c3c(0x232))/0x5+-parseInt(_0x580c3c(0x1c6))/0x6+parseInt(_0x580c3c(0x20f))/0x7*(parseInt(_0x580c3c(0x1ea))/0x8);if(_0x5638c0===_0x127c65)break;else _0x2b7b31['push'](_0x2b7b31['shift']());}catch(_0x1ccc34){_0x2b7b31['push'](_0x2b7b31['shift']());}}}(a0_0x2122,0x4054c));import{ERROR_TYPES,HTTP_STATUS,AGENT_STATUS}from'../utilities/constants.js';export class ErrorHandler{constructor(_0x34d828,_0x453d74){const _0x43c33b=a0_0x864e;this['config']=_0x34d828||{},this[_0x43c33b(0x22e)]=_0x453d74,this[_0x43c33b(0x212)]={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this[_0x43c33b(0x1eb)]=new Map(),this['errorSubscribers']=new Set(),this['errorQueue']=[],this[_0x43c33b(0x1f8)]=![],this[_0x43c33b(0x21c)](),this[_0x43c33b(0x1cf)]();}async['handleError'](_0x2b8f95,_0x5bb5bf={}){const _0x4e2ef2=a0_0x864e;try{const _0x479737=this['classifyError'](_0x2b8f95,_0x5bb5bf),_0x381d23=await this[_0x4e2ef2(0x1c2)](_0x479737);return this[_0x4e2ef2(0x1d3)](_0x479737),this[_0x4e2ef2(0x22c)](_0x479737,_0x381d23),_0x381d23;}catch(_0x30f61f){return this['logger'][_0x4e2ef2(0x1c8)](_0x4e2ef2(0x1d2),{'originalError':_0x2b8f95['message'],'handlingError':_0x30f61f[_0x4e2ef2(0x1f9)]}),{'success':![],'error':_0x30f61f,'recovery':null,'severity':_0x4e2ef2(0x210)};}}[a0_0x25c7e4(0x1e0)](_0xffe26f,_0x2776f9={}){const _0x45a817=a0_0x25c7e4,_0x2e17a5={'id':this['generateErrorId'](),'timestamp':new Date()['toISOString'](),'message':_0xffe26f[_0x45a817(0x1f9)]||_0xffe26f[_0x45a817(0x1ce)](),'stack':_0xffe26f['stack']||null,'code':_0xffe26f['code']||null,'type':this[_0x45a817(0x206)](_0xffe26f,_0x2776f9),'severity':this['determineSeverity'](_0xffe26f,_0x2776f9),'context':{..._0x2776f9},'recoverable':!![],'retryCount':_0x2776f9['retryCount']||0x0,'maxRetries':this['getMaxRetries'](_0xffe26f,_0x2776f9)};return _0x2776f9['agentId']&&(_0x2e17a5['agentId']=_0x2776f9['agentId']),_0x2776f9[_0x45a817(0x21a)]&&(_0x2e17a5['toolId']=_0x2776f9[_0x45a817(0x21a)]),_0x2776f9[_0x45a817(0x224)]&&(_0x2e17a5[_0x45a817(0x224)]=_0x2776f9['operationId']),_0x2e17a5[_0x45a817(0x1d7)]=this['isRecoverable'](_0x2e17a5),_0x2e17a5;}async['processError'](_0x1d8dbb){const _0x14fca2=a0_0x25c7e4;try{this[_0x14fca2(0x22e)]['error'](_0x14fca2(0x1db),{'errorId':_0x1d8dbb['id'],'type':_0x1d8dbb['type'],'severity':_0x1d8dbb['severity'],'agentId':_0x1d8dbb[_0x14fca2(0x1e7)],'message':_0x1d8dbb['message']});_0x1d8dbb[_0x14fca2(0x1fb)]==='critical'&&await this[_0x14fca2(0x1e5)](_0x1d8dbb);let _0x31f352=null;return _0x1d8dbb['recoverable']&&_0x1d8dbb['retryCount']<_0x1d8dbb['maxRetries']&&(_0x31f352=await this[_0x14fca2(0x207)](_0x1d8dbb)),await this[_0x14fca2(0x1c1)](_0x1d8dbb,_0x31f352),{'success':_0x31f352?.[_0x14fca2(0x1f6)]||![],'errorId':_0x1d8dbb['id'],'errorType':_0x1d8dbb['type'],'severity':_0x1d8dbb[_0x14fca2(0x1fb)],'recovery':_0x31f352,'shouldRetry':this['shouldRetry'](_0x1d8dbb,_0x31f352),'retryDelay':this['calculateRetryDelay'](_0x1d8dbb)};}catch(processingError){return this['logger'][_0x14fca2(0x1c8)]('Error\x20processing\x20failed',{'errorId':_0x1d8dbb['id'],'processingError':processingError[_0x14fca2(0x1f9)]}),{'success':![],'errorId':_0x1d8dbb['id'],'errorType':_0x1d8dbb[_0x14fca2(0x1e9)],'severity':'critical','recovery':null,'shouldRetry':![]};}}async[a0_0x25c7e4(0x207)](_0x54e58e){const _0x379646=a0_0x25c7e4;try{this['errorStats']['recoveryAttempts']++;const _0x56ec97=this['recoveryStrategies'][_0x379646(0x21e)](_0x54e58e['type'])||this[_0x379646(0x1eb)][_0x379646(0x21e)]('default');if(!_0x56ec97)return this['logger'][_0x379646(0x1f0)](_0x379646(0x1dd),{'errorType':_0x54e58e[_0x379646(0x1e9)]}),{'success':![],'reason':'No\x20recovery\x20strategy\x20available'};this['logger']['info'](_0x379646(0x20e),{'errorId':_0x54e58e['id'],'errorType':_0x54e58e[_0x379646(0x1e9)],'strategy':_0x56ec97['name'],'retryCount':_0x54e58e[_0x379646(0x1ef)]});const _0x522488=await _0x56ec97[_0x379646(0x20b)](_0x54e58e);return _0x522488['success']?(this['errorStats']['successfulRecoveries']++,this['logger'][_0x379646(0x217)]('Error\x20recovery\x20successful',{'errorId':_0x54e58e['id'],'strategy':_0x56ec97['name']})):this[_0x379646(0x22e)][_0x379646(0x1f0)](_0x379646(0x202),{'errorId':_0x54e58e['id'],'strategy':_0x56ec97[_0x379646(0x22b)],'reason':_0x522488[_0x379646(0x1dc)]}),_0x522488;}catch(_0x2a2a79){return this['logger'][_0x379646(0x1c8)]('Recovery\x20attempt\x20failed',{'errorId':_0x54e58e['id'],'recoveryError':_0x2a2a79[_0x379646(0x1f9)]}),{'success':![],'reason':_0x379646(0x1fc)+_0x2a2a79['message']};}}async[a0_0x25c7e4(0x1e5)](_0x3b81b3){const _0xbe016d=a0_0x25c7e4;try{this['errorStats'][_0xbe016d(0x21f)]++,this[_0xbe016d(0x22e)][_0xbe016d(0x1c8)](_0xbe016d(0x215),{'errorId':_0x3b81b3['id'],'message':_0x3b81b3[_0xbe016d(0x1f9)],'context':_0x3b81b3['context']});typeof process!==_0xbe016d(0x211)&&process['emit']&&process[_0xbe016d(0x21d)]('criticalError',_0x3b81b3);switch(_0x3b81b3['type']){case ERROR_TYPES[_0xbe016d(0x1ec)]:await this[_0xbe016d(0x214)](_0x3b81b3);break;case ERROR_TYPES[_0xbe016d(0x1e2)]:await this[_0xbe016d(0x1cd)](_0x3b81b3);break;case ERROR_TYPES['OPERATION_TIMEOUT']:await this['handleOperationTimeout'](_0x3b81b3);break;default:await this['handleGenericCriticalError'](_0x3b81b3);}}catch(_0x450383){this['logger']['error'](_0xbe016d(0x1fd),{'errorId':_0x3b81b3['id'],'handlingError':_0x450383['message']});}}['determineErrorType'](_0x321021,_0xa51bcf){const _0x4bf018=a0_0x25c7e4;if(_0x321021['code']===_0x4bf018(0x1ff)||_0x321021[_0x4bf018(0x231)]===HTTP_STATUS['NOT_FOUND'])return ERROR_TYPES['FILE_NOT_FOUND'];if(_0x321021[_0x4bf018(0x226)]===_0x4bf018(0x227)||_0x321021['status']===HTTP_STATUS[_0x4bf018(0x1c3)])return ERROR_TYPES[_0x4bf018(0x1f1)];if(_0x321021['status']===HTTP_STATUS['UNAUTHORIZED'])return ERROR_TYPES['AUTHENTICATION_FAILED'];if(_0x321021[_0x4bf018(0x231)]===HTTP_STATUS['TOO_MANY_REQUESTS'])return ERROR_TYPES[_0x4bf018(0x1e2)];const _0x4895c9=_0x321021['message']?.['toLowerCase']()||'';if(_0x4895c9['includes'](_0x4bf018(0x234))||_0x4895c9[_0x4bf018(0x219)](_0x4bf018(0x1d8)))return ERROR_TYPES[_0x4bf018(0x22a)];if(_0x4895c9['includes']('validation')||_0x4895c9[_0x4bf018(0x219)](_0x4bf018(0x208)))return ERROR_TYPES[_0x4bf018(0x22f)];if(_0x4895c9['includes']('config')||_0x4895c9['includes']('configuration'))return ERROR_TYPES['CONFIGURATION_ERROR'];if(_0xa51bcf[_0x4bf018(0x201)]===_0x4bf018(0x20c))return ERROR_TYPES[_0x4bf018(0x22d)];if(_0xa51bcf['operation']==='api_request')return ERROR_TYPES[_0x4bf018(0x1e2)];return ERROR_TYPES[_0x4bf018(0x223)];}['determineSeverity'](_0x480a2d,_0x10dfd1){const _0x107c6e=a0_0x25c7e4,_0x228103=[ERROR_TYPES[_0x107c6e(0x1ec)],ERROR_TYPES['CONFIGURATION_ERROR']],_0x450193=[ERROR_TYPES[_0x107c6e(0x1e2)],ERROR_TYPES['OPERATION_TIMEOUT'],ERROR_TYPES[_0x107c6e(0x1f1)]],_0x5f5230=this[_0x107c6e(0x206)](_0x480a2d,_0x10dfd1);if(_0x228103[_0x107c6e(0x219)](_0x5f5230))return _0x107c6e(0x210);if(_0x450193[_0x107c6e(0x219)](_0x5f5230))return'high';const _0x48f57c=_0x10dfd1&&_0x10dfd1[_0x107c6e(0x1ef)]||0x0;if(_0x48f57c>=0x3)return _0x107c6e(0x228);if(_0x10dfd1&&_0x10dfd1['agentId']&&_0x10dfd1['operation']==='agent_communication')return'medium';return _0x107c6e(0x221);}[a0_0x25c7e4(0x1cb)](_0x4c2518){const _0x477b2d=a0_0x25c7e4,_0x2ed50b=[ERROR_TYPES['AUTHENTICATION_FAILED'],ERROR_TYPES[_0x477b2d(0x204)]];if(_0x2ed50b[_0x477b2d(0x219)](_0x4c2518[_0x477b2d(0x1e9)]))return![];if(_0x4c2518[_0x477b2d(0x1ef)]>=_0x4c2518['maxRetries'])return![];if(_0x4c2518[_0x477b2d(0x1fb)]===_0x477b2d(0x210))return![];return!![];}[a0_0x25c7e4(0x200)](_0x71078e,_0x26709b){const _0x31006b=a0_0x25c7e4,_0x3efb77=this[_0x31006b(0x206)](_0x71078e,_0x26709b),_0x4baa5c={[ERROR_TYPES['RATE_LIMIT_EXCEEDED']]:0x5,[ERROR_TYPES['OPERATION_TIMEOUT']]:0x3,[ERROR_TYPES['FILE_NOT_FOUND']]:0x2,[ERROR_TYPES['PERMISSION_DENIED']]:0x1,[ERROR_TYPES[_0x31006b(0x22f)]]:0x2,[ERROR_TYPES['UNKNOWN_ERROR']]:0x3};return _0x4baa5c[_0x3efb77]||0x3;}[a0_0x25c7e4(0x1d0)](_0x203762,_0x388de7){const _0x1a6a24=a0_0x25c7e4;if(!_0x203762['recoverable'])return![];if(_0x203762[_0x1a6a24(0x1ef)]>=_0x203762['maxRetries'])return![];if(_0x388de7&&_0x388de7['success'])return![];return!![];}[a0_0x25c7e4(0x205)](_0x22d262){const _0x39d926=a0_0x25c7e4,_0x4adedf=0x3e8,_0x537440=0x7530,_0x12c345=_0x4adedf*Math[_0x39d926(0x1e3)](0x2,_0x22d262['retryCount']),_0x3efe0c=Math[_0x39d926(0x1f7)]()*0x3e8;return Math['min'](_0x12c345+_0x3efe0c,_0x537440);}[a0_0x25c7e4(0x21c)](){const _0x13cdf1=a0_0x25c7e4;this['recoveryStrategies'][_0x13cdf1(0x209)](ERROR_TYPES['FILE_NOT_FOUND'],{'name':_0x13cdf1(0x1f4),'recover':async _0x398e1b=>{const _0x1f023b=_0x13cdf1;if(_0x398e1b['context'][_0x1f023b(0x218)])return{'success':![],'reason':_0x1f023b(0x1c5),'suggestion':'Check\x20file\x20path\x20and\x20permissions'};return{'success':![],'reason':_0x1f023b(0x225)};}}),this['recoveryStrategies'][_0x13cdf1(0x209)](ERROR_TYPES['RATE_LIMIT_EXCEEDED'],{'name':'rate_limit_recovery','recover':async _0x3d7f7e=>{const _0x38d64f=_0x13cdf1,_0x4d3db2=this['calculateRateLimitWait'](_0x3d7f7e);return this['logger']['info']('Waiting\x20for\x20rate\x20limit\x20recovery',{'waitTime':_0x4d3db2}),await new Promise(_0x2fdde1=>setTimeout(_0x2fdde1,_0x4d3db2)),{'success':!![],'action':_0x38d64f(0x1e8),'waitTime':_0x4d3db2};}}),this['recoveryStrategies'][_0x13cdf1(0x209)](ERROR_TYPES['OPERATION_TIMEOUT'],{'name':'timeout_recovery','recover':async _0x4fad32=>{const _0x1eb58c=_0x13cdf1;if(_0x4fad32['context']['timeout']){const _0x478d99=Math['min'](_0x4fad32[_0x1eb58c(0x1fe)][_0x1eb58c(0x234)]*1.5,0x493e0);return{'success':!![],'action':'increased_timeout','newTimeout':_0x478d99};}return{'success':![],'reason':_0x1eb58c(0x1e1)};}}),this['recoveryStrategies'][_0x13cdf1(0x209)](ERROR_TYPES[_0x13cdf1(0x1f1)],{'name':_0x13cdf1(0x1fa),'recover':async _0x4a0b0c=>{const _0x66ad5c=_0x13cdf1;return{'success':![],'reason':_0x66ad5c(0x1f5),'suggestion':'Check\x20file/directory\x20permissions'};}}),this['recoveryStrategies'][_0x13cdf1(0x209)](ERROR_TYPES['VALIDATION_ERROR'],{'name':_0x13cdf1(0x1c4),'recover':async _0x4175e7=>{const _0x2e5a4a=_0x13cdf1;if(_0x4175e7[_0x2e5a4a(0x1fe)][_0x2e5a4a(0x1cc)])return{'success':!![],'action':_0x2e5a4a(0x1ed),'suggestion':_0x2e5a4a(0x1ca)};return{'success':![],'reason':'No\x20input\x20data\x20to\x20sanitize'};}}),this['recoveryStrategies'][_0x13cdf1(0x209)]('default',{'name':'default_recovery','recover':async _0x50a1ec=>{const _0x14d3e6=_0x13cdf1,_0x117326=this[_0x14d3e6(0x205)](_0x50a1ec);return await new Promise(_0x3c89c9=>setTimeout(_0x3c89c9,_0x117326)),{'success':!![],'action':'delay_retry','delay':_0x117326};}});}async['handleAuthenticationFailure'](_0x31b372){this['logger']['error']('Authentication\x20failure\x20detected',{'errorId':_0x31b372['id']});if(_0x31b372['agentId']){}}async['handleRateLimitExceeded'](_0x458ddd){const _0x1a3387=a0_0x25c7e4,_0x4151f9=this['calculateRateLimitWait'](_0x458ddd);this['logger']['warn'](_0x1a3387(0x1de),{'errorId':_0x458ddd['id'],'waitTime':_0x4151f9,'agentId':_0x458ddd['agentId']});if(_0x458ddd[_0x1a3387(0x1e7)]){}}async[a0_0x25c7e4(0x1e4)](_0xa767a9){const _0x47b584=a0_0x25c7e4;this['logger'][_0x47b584(0x1c8)]('Operation\x20timeout\x20detected',{'errorId':_0xa767a9['id'],'operation':_0xa767a9['context']['operation'],'timeout':_0xa767a9['context'][_0x47b584(0x234)]});}async[a0_0x25c7e4(0x222)](_0x48e738){const _0x19e686=a0_0x25c7e4;this[_0x19e686(0x22e)][_0x19e686(0x1c8)](_0x19e686(0x1c0),{'errorId':_0x48e738['id'],'type':_0x48e738[_0x19e686(0x1e9)],'message':_0x48e738['message']}),_0x48e738['agentId']&&this['logger'][_0x19e686(0x1f0)]('Considering\x20agent\x20pause\x20due\x20to\x20critical\x20error',{'agentId':_0x48e738['agentId']});}['calculateRateLimitWait'](_0x3f7a74){const _0x4d6845=0xea60,_0xa84534=Math['pow'](0x2,_0x3f7a74['retryCount']),_0x2838c5=0x493e0;return Math['min'](_0x4d6845*_0xa84534,_0x2838c5);}async['logError'](_0x18d634,_0x4665ec){const _0x317cec=a0_0x25c7e4;try{const _0x598c2f={'errorId':_0x18d634['id'],'timestamp':_0x18d634[_0x317cec(0x203)],'type':_0x18d634[_0x317cec(0x1e9)],'severity':_0x18d634[_0x317cec(0x1fb)],'message':_0x18d634[_0x317cec(0x1f9)],'agentId':_0x18d634[_0x317cec(0x1e7)],'toolId':_0x18d634[_0x317cec(0x21a)],'operationId':_0x18d634['operationId'],'retryCount':_0x18d634[_0x317cec(0x1ef)],'recoveryAttempted':!!_0x4665ec,'recoverySuccess':_0x4665ec?.[_0x317cec(0x1f6)]||![],'recoveryAction':_0x4665ec?.['action']||null};this['errorQueue']['push'](_0x598c2f),!this[_0x317cec(0x1f8)]&&this['processErrorQueue']();}catch(_0x112f41){this[_0x317cec(0x22e)][_0x317cec(0x1c8)](_0x317cec(0x1d4),{'errorId':_0x18d634['id'],'loggingError':_0x112f41['message']});}}async['processErrorQueue'](){const _0x53287d=a0_0x25c7e4;if(this['isProcessingQueue']||this['errorQueue'][_0x53287d(0x20d)]===0x0)return;this[_0x53287d(0x1f8)]=!![];try{while(this['errorQueue']['length']>0x0){const _0x146f0a=this[_0x53287d(0x1df)]['splice'](0x0,0xa);this[_0x53287d(0x22e)]['debug'](_0x53287d(0x230),{'batchSize':_0x146f0a['length']}),await new Promise(_0x1dc5c0=>setTimeout(_0x1dc5c0,0x64));}}catch(processingError){this['logger'][_0x53287d(0x1c8)]('Error\x20queue\x20processing\x20failed',{'error':processingError[_0x53287d(0x1f9)]});}finally{this['isProcessingQueue']=![];}}['setupErrorProcessing'](){const _0x3318d9=a0_0x25c7e4;setInterval(()=>{const _0x4206f1=a0_0x864e;this[_0x4206f1(0x1df)][_0x4206f1(0x20d)]>0x0&&this['processErrorQueue']();},0x1388),typeof process!==_0x3318d9(0x211)&&(process['on']('uncaughtException',_0x3a32a8=>{const _0x5f1f8f=_0x3318d9;this['handleError'](_0x3a32a8,{'type':'uncaught_exception','severity':_0x5f1f8f(0x210)});}),process['on'](_0x3318d9(0x1d5),(_0x42bfe0,_0x47b105)=>{const _0x652516=_0x3318d9;this[_0x652516(0x21b)](new Error('Unhandled\x20Rejection:\x20'+_0x42bfe0),{'type':_0x652516(0x1c9),'severity':'high','promise':_0x47b105['toString']()});}));}[a0_0x25c7e4(0x1d3)](_0x4440ce){const _0x92d917=a0_0x25c7e4;this[_0x92d917(0x212)][_0x92d917(0x229)]++,!this[_0x92d917(0x212)]['errorsByType'][_0x92d917(0x220)](_0x4440ce['type'])&&this['errorStats']['errorsByType'][_0x92d917(0x209)](_0x4440ce['type'],0x0),this[_0x92d917(0x212)]['errorsByType']['set'](_0x4440ce['type'],this['errorStats'][_0x92d917(0x216)]['get'](_0x4440ce['type'])+0x1),_0x4440ce['agentId']&&(!this[_0x92d917(0x212)][_0x92d917(0x1d6)]['has'](_0x4440ce[_0x92d917(0x1e7)])&&this[_0x92d917(0x212)][_0x92d917(0x1d6)][_0x92d917(0x209)](_0x4440ce['agentId'],0x0),this[_0x92d917(0x212)]['errorsByAgent']['set'](_0x4440ce[_0x92d917(0x1e7)],this[_0x92d917(0x212)][_0x92d917(0x1d6)]['get'](_0x4440ce[_0x92d917(0x1e7)])+0x1));}['subscribe'](_0x1bc500){const _0xa741fb=a0_0x25c7e4;return this[_0xa741fb(0x1ee)][_0xa741fb(0x20a)](_0x1bc500),()=>this['errorSubscribers'][_0xa741fb(0x1f3)](_0x1bc500);}[a0_0x25c7e4(0x22c)](_0x3595c3,_0x53621a){const _0x11d5fe=a0_0x25c7e4;this[_0x11d5fe(0x1ee)][_0x11d5fe(0x1f2)](_0x52f844=>{const _0x2fd053=_0x11d5fe;try{_0x52f844(_0x3595c3,_0x53621a);}catch(_0x58e7d8){this[_0x2fd053(0x22e)]['error']('Error\x20subscriber\x20callback\x20failed',{'error':_0x58e7d8[_0x2fd053(0x1f9)]});}});}['generateErrorId'](){const _0x54c7fb=a0_0x25c7e4;return'err_'+Date['now']()+'_'+Math[_0x54c7fb(0x1f7)]()['toString'](0x24)['substr'](0x2,0x9);}['getErrorStats'](){const _0x4918c5=a0_0x25c7e4;return{'totalErrors':this['errorStats'][_0x4918c5(0x229)],'errorsByType':Object[_0x4918c5(0x1d1)](this['errorStats']['errorsByType']),'errorsByAgent':Object[_0x4918c5(0x1d1)](this['errorStats'][_0x4918c5(0x1d6)]),'recoveryAttempts':this[_0x4918c5(0x212)]['recoveryAttempts'],'successfulRecoveries':this[_0x4918c5(0x212)]['successfulRecoveries'],'recoverySuccessRate':this['errorStats'][_0x4918c5(0x233)]>0x0?this['errorStats']['successfulRecoveries']/this['errorStats']['recoveryAttempts']:0x0,'criticalErrors':this[_0x4918c5(0x212)]['criticalErrors'],'queueLength':this[_0x4918c5(0x1df)][_0x4918c5(0x20d)]};}[a0_0x25c7e4(0x1e6)](){const _0x4da38f=a0_0x25c7e4;this['errorStats']={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this[_0x4da38f(0x1df)]=[];}}export default ErrorHandler;
|