snow-flow 3.0.9 → 3.0.13

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.
Files changed (302) hide show
  1. package/claude-flow.bat +0 -0
  2. package/claude-flow.ps1 +0 -0
  3. package/dist/mcp/intelligent-reporting-mcp.d.ts +7 -0
  4. package/dist/mcp/intelligent-reporting-mcp.js +379 -0
  5. package/dist/mcp/servicenow-automation-mcp.js +0 -0
  6. package/dist/mcp/servicenow-deployment-mcp.js +0 -0
  7. package/dist/mcp/servicenow-integration-mcp.js +0 -0
  8. package/dist/mcp/servicenow-mcp-server.js +0 -0
  9. package/dist/mcp/servicenow-operations-mcp.js +0 -0
  10. package/dist/mcp/servicenow-platform-development-mcp.js +0 -0
  11. package/dist/mcp/servicenow-progressive-indexer.js +0 -0
  12. package/dist/mcp/servicenow-reporting-analytics-mcp.js +280 -29
  13. package/dist/mcp/servicenow-security-compliance-mcp.js +0 -0
  14. package/dist/mcp/servicenow-update-set-mcp.js +0 -0
  15. package/dist/mcp/start-all-mcp-servers.js +0 -0
  16. package/dist/mcp/start-servicenow-mcp.js +0 -0
  17. package/dist/services/widget-deployment-service.d.ts +2 -1
  18. package/dist/services/widget-deployment-service.js +17 -16
  19. package/dist/utils/anti-mock-data-validator.d.ts +66 -0
  20. package/dist/utils/anti-mock-data-validator.js +316 -0
  21. package/dist/utils/servicenow-eventual-consistency.d.ts +120 -0
  22. package/dist/utils/servicenow-eventual-consistency.js +220 -0
  23. package/memory/agents/README.md +1 -1
  24. package/memory/claude-flow-data.json +1 -1
  25. package/memory/sessions/README.md +1 -1
  26. package/package.json +4 -3
  27. package/.mcp.json +0 -22
  28. package/claude-flow.config.json +0 -20
  29. package/dist/agents/app-creator.agent.d.ts +0 -55
  30. package/dist/agents/app-creator.agent.js +0 -1292
  31. package/dist/agents/base/base-snow-agent.d.ts +0 -75
  32. package/dist/agents/base/base-snow-agent.js +0 -169
  33. package/dist/agents/base-snow-agent.d.ts +0 -63
  34. package/dist/agents/base-snow-agent.js +0 -296
  35. package/dist/agents/coordinator.d.ts +0 -200
  36. package/dist/agents/coordinator.js +0 -777
  37. package/dist/agents/flow-builder-agent.d.ts +0 -18
  38. package/dist/agents/flow-builder-agent.js +0 -197
  39. package/dist/agents/queen-403-handler.d.ts +0 -47
  40. package/dist/agents/queen-403-handler.js +0 -175
  41. package/dist/agents/queen-agent-example.d.ts +0 -23
  42. package/dist/agents/queen-agent-example.js +0 -240
  43. package/dist/agents/queen-agent.test.d.ts +0 -6
  44. package/dist/agents/script-generator.agent.d.ts +0 -32
  45. package/dist/agents/script-generator.agent.js +0 -772
  46. package/dist/agents/script-writer-agent.d.ts +0 -22
  47. package/dist/agents/script-writer-agent.js +0 -695
  48. package/dist/agents/security-agent.d.ts +0 -23
  49. package/dist/agents/security-agent.js +0 -619
  50. package/dist/agents/specialists/automation-specialist.agent.d.ts +0 -44
  51. package/dist/agents/specialists/automation-specialist.agent.js +0 -204
  52. package/dist/agents/specialists/data-specialist.agent.d.ts +0 -165
  53. package/dist/agents/specialists/data-specialist.agent.js +0 -484
  54. package/dist/agents/specialists/integration-specialist.agent.d.ts +0 -227
  55. package/dist/agents/specialists/integration-specialist.agent.js +0 -725
  56. package/dist/agents/specialists/reporting-specialist.agent.d.ts +0 -54
  57. package/dist/agents/specialists/reporting-specialist.agent.js +0 -193
  58. package/dist/agents/specialists/security-specialist.agent.d.ts +0 -85
  59. package/dist/agents/specialists/security-specialist.agent.js +0 -309
  60. package/dist/agents/teams/adaptive/adaptive-coordinator.agent.d.ts +0 -111
  61. package/dist/agents/teams/adaptive/adaptive-coordinator.agent.js +0 -383
  62. package/dist/agents/teams/base-team.d.ts +0 -72
  63. package/dist/agents/teams/base-team.js +0 -253
  64. package/dist/agents/teams/team-types.d.ts +0 -265
  65. package/dist/agents/teams/team-types.js +0 -3
  66. package/dist/agents/teams/widget/widget-architect.agent.d.ts +0 -61
  67. package/dist/agents/teams/widget/widget-architect.agent.js +0 -436
  68. package/dist/agents/teams/widget/widget-backend.agent.d.ts +0 -74
  69. package/dist/agents/teams/widget/widget-backend.agent.js +0 -1531
  70. package/dist/agents/teams/widget/widget-frontend.agent.d.ts +0 -67
  71. package/dist/agents/teams/widget/widget-frontend.agent.js +0 -1014
  72. package/dist/agents/teams/widget/widget-platform.agent.d.ts +0 -90
  73. package/dist/agents/teams/widget/widget-platform.agent.js +0 -1190
  74. package/dist/agents/teams/widget/widget-uiux.agent.d.ts +0 -107
  75. package/dist/agents/teams/widget/widget-uiux.agent.js +0 -1033
  76. package/dist/agents/test-agent.d.ts +0 -26
  77. package/dist/agents/test-agent.js +0 -734
  78. package/dist/agents/test-agents.d.ts +0 -7
  79. package/dist/agents/test-agents.js +0 -64
  80. package/dist/agents/ui-builder.agent.d.ts +0 -50
  81. package/dist/agents/ui-builder.agent.js +0 -1539
  82. package/dist/agents/widget-builder.agent.d.ts +0 -32
  83. package/dist/agents/widget-builder.agent.js +0 -439
  84. package/dist/agents/widget-creator-agent.d.ts +0 -18
  85. package/dist/agents/widget-creator-agent.js +0 -498
  86. package/dist/agents/workflow-designer.agent.d.ts +0 -31
  87. package/dist/agents/workflow-designer.agent.js +0 -583
  88. package/dist/api/error-handling.d.ts +0 -325
  89. package/dist/api/error-handling.js +0 -1488
  90. package/dist/api/flow-designer-api.d.ts +0 -167
  91. package/dist/api/flow-designer-api.js +0 -554
  92. package/dist/api/natural-language-mapper.d.ts +0 -124
  93. package/dist/api/natural-language-mapper.js +0 -501
  94. package/dist/api/performance-optimizer.d.ts +0 -240
  95. package/dist/api/performance-optimizer.js +0 -706
  96. package/dist/api/transaction-manager.d.ts +0 -189
  97. package/dist/api/transaction-manager.js +0 -576
  98. package/dist/assembly/team-assembler.d.ts +0 -140
  99. package/dist/assembly/team-assembler.js +0 -502
  100. package/dist/benchmark-performance.d.ts +0 -41
  101. package/dist/benchmark-performance.js +0 -230
  102. package/dist/cli/snow-flow-cli-integration.d.ts +0 -30
  103. package/dist/cli/snow-flow-cli-integration.js +0 -396
  104. package/dist/coordination/coordination-engine.d.ts +0 -41
  105. package/dist/coordination/coordination-engine.js +0 -324
  106. package/dist/coordination/coordination.test.d.ts +0 -6
  107. package/dist/coordination/example.d.ts +0 -31
  108. package/dist/coordination/example.js +0 -394
  109. package/dist/coordination/execution-patterns.d.ts +0 -43
  110. package/dist/coordination/execution-patterns.js +0 -507
  111. package/dist/coordination/factory.d.ts +0 -94
  112. package/dist/coordination/factory.js +0 -433
  113. package/dist/coordination/index.d.ts +0 -71
  114. package/dist/coordination/index.js +0 -135
  115. package/dist/coordination/progress-monitor.d.ts +0 -71
  116. package/dist/coordination/progress-monitor.js +0 -505
  117. package/dist/coordination/quality-gates.d.ts +0 -124
  118. package/dist/coordination/quality-gates.js +0 -577
  119. package/dist/coordination/shared-memory.d.ts +0 -39
  120. package/dist/coordination/shared-memory.js +0 -289
  121. package/dist/coordination/task-dependencies.d.ts +0 -50
  122. package/dist/coordination/task-dependencies.js +0 -407
  123. package/dist/coordination/team-coordinator.d.ts +0 -59
  124. package/dist/coordination/team-coordinator.js +0 -550
  125. package/dist/coordination/types.d.ts +0 -152
  126. package/dist/coordination/types.js +0 -3
  127. package/dist/mcp/mcp-wrapper.d.ts +0 -8
  128. package/dist/mcp/mcp-wrapper.js +0 -77
  129. package/dist/mcp/servicenow-flow-composer-enhanced.js +0 -396
  130. package/dist/mcp/servicenow-flow-composer-mcp.d.ts +0 -7
  131. package/dist/mcp/servicenow-flow-composer-mcp.js +0 -3103
  132. package/dist/mcp/servicenow-graph-memory-mcp.d.ts +0 -7
  133. package/dist/mcp/servicenow-intelligent-mcp.d.ts +0 -143
  134. package/dist/mcp/servicenow-intelligent-mcp.js +0 -4156
  135. package/dist/mcp/servicenow-xml-flow-mcp.d.ts +0 -53
  136. package/dist/mcp/servicenow-xml-flow-mcp.js +0 -1704
  137. package/dist/mcp/singleton-check.js +0 -31
  138. package/dist/mcp/test-simple-mcp.d.ts +0 -6
  139. package/dist/mcp/test-simple-mcp.js +0 -63
  140. package/dist/memory/hierarchical-memory-system.d.ts +0 -90
  141. package/dist/memory/hierarchical-memory-system.js +0 -400
  142. package/dist/memory/index.d.ts +0 -9
  143. package/dist/memory/index.js +0 -20
  144. package/dist/memory/mcp-integration-example.d.ts +0 -6
  145. package/dist/memory/mcp-integration-example.js +0 -281
  146. package/dist/memory/memory-client.d.ts +0 -199
  147. package/dist/memory/memory-client.js +0 -364
  148. package/dist/memory/memory-manager.d.ts +0 -29
  149. package/dist/memory/memory-manager.js +0 -280
  150. package/dist/memory/memory-operations.d.ts +0 -179
  151. package/dist/memory/memory-operations.js +0 -691
  152. package/dist/memory/memory-system.d.ts +0 -153
  153. package/dist/memory/memory-system.js +0 -651
  154. package/dist/memory/memory-test.d.ts +0 -6
  155. package/dist/memory/memory-test.js +0 -161
  156. package/dist/memory/snow-flow-memory-patterns.d.ts +0 -213
  157. package/dist/memory/snow-flow-memory-patterns.js +0 -200
  158. package/dist/memory/snow-memory.d.ts +0 -54
  159. package/dist/memory/snow-memory.js +0 -301
  160. package/dist/memory/swarm-memory.d.ts +0 -135
  161. package/dist/memory/swarm-memory.js +0 -378
  162. package/dist/optimization/flow-performance-optimizer.js +0 -723
  163. package/dist/orchestration/discovery/service-discovery.d.ts +0 -81
  164. package/dist/orchestration/discovery/service-discovery.js +0 -808
  165. package/dist/orchestration/distributed-orchestrator.d.ts +0 -131
  166. package/dist/orchestration/distributed-orchestrator.js +0 -712
  167. package/dist/orchestration/distribution/task-distribution-engine.d.ts +0 -53
  168. package/dist/orchestration/distribution/task-distribution-engine.js +0 -586
  169. package/dist/orchestration/flow-update-orchestrator.js +0 -648
  170. package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts +0 -606
  171. package/dist/orchestration/interfaces/distributed-orchestration.interface.js +0 -65
  172. package/dist/orchestration/protocols/mcpx-protocol.d.ts +0 -71
  173. package/dist/orchestration/protocols/mcpx-protocol.js +0 -668
  174. package/dist/orchestration/state/distributed-state-manager.d.ts +0 -89
  175. package/dist/orchestration/state/distributed-state-manager.js +0 -716
  176. package/dist/orchestrator/flow-composer.d.ts +0 -105
  177. package/dist/orchestrator/flow-composer.js +0 -404
  178. package/dist/orchestrator/flow-pattern-templates.d.ts +0 -260
  179. package/dist/orchestrator/flow-pattern-templates.js +0 -908
  180. package/dist/orchestrator/flow-subflow-decision-engine.d.ts +0 -202
  181. package/dist/orchestrator/flow-subflow-decision-engine.js +0 -769
  182. package/dist/orchestrator/flow-validation-engine.d.ts +0 -169
  183. package/dist/orchestrator/flow-validation-engine.js +0 -913
  184. package/dist/orchestrator/snow-orchestrator.d.ts +0 -49
  185. package/dist/orchestrator/snow-orchestrator.js +0 -235
  186. package/dist/orchestrator/subflow-creation-handler.d.ts +0 -230
  187. package/dist/orchestrator/subflow-creation-handler.js +0 -791
  188. package/dist/patterns/adaptive-patterns.d.ts +0 -140
  189. package/dist/patterns/adaptive-patterns.js +0 -549
  190. package/dist/queen/advanced-integration-test.d.ts +0 -48
  191. package/dist/queen/advanced-integration-test.js +0 -473
  192. package/dist/queen/integration-example.d.ts +0 -82
  193. package/dist/queen/integration-example.js +0 -219
  194. package/dist/queen/integration-test.d.ts +0 -72
  195. package/dist/queen/integration-test.js +0 -563
  196. package/dist/queen/mock-mcp-client.d.ts +0 -71
  197. package/dist/queen/mock-mcp-client.js +0 -317
  198. package/dist/queen/run-integration-tests.d.ts +0 -9
  199. package/dist/queen/run-integration-tests.js +0 -27
  200. package/dist/sparc/coordinators/adaptive-coordinator.d.ts +0 -54
  201. package/dist/sparc/coordinators/adaptive-coordinator.js +0 -367
  202. package/dist/sparc/coordinators/team-coordinator.d.ts +0 -66
  203. package/dist/sparc/coordinators/team-coordinator.js +0 -402
  204. package/dist/sparc/modes/team-modes.d.ts +0 -33
  205. package/dist/sparc/modes/team-modes.js +0 -399
  206. package/dist/sparc/teams/application-team.d.ts +0 -73
  207. package/dist/sparc/teams/application-team.js +0 -463
  208. package/dist/sparc/teams/flow-team.d.ts +0 -67
  209. package/dist/sparc/teams/flow-team.js +0 -373
  210. package/dist/sparc/teams/widget-team.d.ts +0 -61
  211. package/dist/sparc/teams/widget-team.js +0 -280
  212. package/dist/specialists/app-specialists.d.ts +0 -93
  213. package/dist/specialists/app-specialists.js +0 -1639
  214. package/dist/specialists/base-specialist.d.ts +0 -19
  215. package/dist/specialists/base-specialist.js +0 -54
  216. package/dist/specialists/flow-specialists.d.ts +0 -113
  217. package/dist/specialists/flow-specialists.js +0 -1787
  218. package/dist/specialists/individual-specialists.d.ts +0 -67
  219. package/dist/specialists/individual-specialists.js +0 -632
  220. package/dist/specialists/widget-specialists.d.ts +0 -70
  221. package/dist/specialists/widget-specialists.js +0 -1264
  222. package/dist/src/utils/agent-detector.js +0 -655
  223. package/dist/teams/adaptive-team.d.ts +0 -81
  224. package/dist/teams/adaptive-team.js +0 -1153
  225. package/dist/teams/application-team.d.ts +0 -30
  226. package/dist/teams/application-team.js +0 -547
  227. package/dist/teams/base-team.d.ts +0 -55
  228. package/dist/teams/base-team.js +0 -243
  229. package/dist/teams/flow-team.d.ts +0 -28
  230. package/dist/teams/flow-team.js +0 -525
  231. package/dist/teams/widget-team.d.ts +0 -26
  232. package/dist/teams/widget-team.js +0 -459
  233. package/dist/templates/flow-template-system.js +0 -625
  234. package/dist/test-fetch-incidents.d.ts +0 -2
  235. package/dist/test-fetch-incidents.js +0 -84
  236. package/dist/test-incident-access.d.ts +0 -2
  237. package/dist/test-incident-access.js +0 -72
  238. package/dist/test-iphone-flow.js +0 -189
  239. package/dist/test-limit-problem.d.ts +0 -2
  240. package/dist/test-limit-problem.js +0 -60
  241. package/dist/test-ml-batch-fix.d.ts +0 -2
  242. package/dist/test-ml-batch-fix.js +0 -104
  243. package/dist/test-ml-batch.d.ts +0 -2
  244. package/dist/test-ml-batch.js +0 -87
  245. package/dist/test-ml-query.d.ts +0 -2
  246. package/dist/test-ml-query.js +0 -100
  247. package/dist/test-ml-training-fix.d.ts +0 -12
  248. package/dist/test-ml-training-fix.js +0 -113
  249. package/dist/test-ml-training.d.ts +0 -2
  250. package/dist/test-ml-training.js +0 -32
  251. package/dist/test-operations-query.d.ts +0 -2
  252. package/dist/test-operations-query.js +0 -84
  253. package/dist/test-performance-query.d.ts +0 -2
  254. package/dist/test-performance-query.js +0 -52
  255. package/dist/test-singleton-protection.d.ts +0 -8
  256. package/dist/test-singleton-protection.js +0 -110
  257. package/dist/test-smart-limits.d.ts +0 -13
  258. package/dist/test-smart-limits.js +0 -100
  259. package/dist/test-snow-query-incidents.d.ts +0 -2
  260. package/dist/test-snow-query-incidents.js +0 -66
  261. package/dist/test-universal-query.d.ts +0 -2
  262. package/dist/test-universal-query.js +0 -106
  263. package/dist/testing/flow-testing-automation.js +0 -641
  264. package/dist/utils/complete-flow-xml-generator.js +0 -1285
  265. package/dist/utils/file-storage-fallback.d.ts +0 -62
  266. package/dist/utils/file-storage-fallback.js +0 -289
  267. package/dist/utils/flow-api-discovery.d.ts +0 -151
  268. package/dist/utils/flow-api-discovery.js +0 -439
  269. package/dist/utils/flow-examples.js +0 -720
  270. package/dist/utils/flow-structure-builder.js +0 -677
  271. package/dist/utils/flow-xml-generator.d.ts +0 -41
  272. package/dist/utils/flow-xml-generator.js +0 -258
  273. package/dist/utils/improved-flow-xml-generator.js +0 -820
  274. package/dist/utils/mcp-process-manager.backup.d.ts +0 -58
  275. package/dist/utils/mcp-process-manager.backup.js +0 -220
  276. package/dist/utils/mcp-singleton-enforcer.d.ts +0 -36
  277. package/dist/utils/mcp-singleton-enforcer.js +0 -201
  278. package/dist/utils/mcp-timeout-fix.d.ts +0 -53
  279. package/dist/utils/mcp-timeout-fix.js +0 -221
  280. package/dist/utils/migrate-claude-flow.d.ts +0 -22
  281. package/dist/utils/migrate-claude-flow.js +0 -120
  282. package/dist/utils/scope-utils.d.ts +0 -72
  283. package/dist/utils/scope-utils.js +0 -386
  284. package/dist/utils/snow-oauth-old.d.ts +0 -65
  285. package/dist/utils/snow-oauth-old.js +0 -345
  286. package/dist/utils/xml-first-flow-generator.js +0 -513
  287. package/memory/servicenow_artifacts/000d9224c895221055906c7518aa2d3d.json +0 -30
  288. package/memory/servicenow_artifacts/0196b66173303010e46b4a2214f6a7a2.json +0 -36
  289. package/memory/servicenow_artifacts/125e5d1d837e2a102a7ea130ceaad397.json +0 -30
  290. package/memory/servicenow_artifacts/7637c1f2b7112210a5e5911cde11a972.json +0 -30
  291. package/memory/servicenow_artifacts/default_documentation_tables_1754056582292.json +0 -55
  292. package/memory/servicenow_artifacts/default_documentation_tables_1754057477189.json +0 -55
  293. package/memory/update-set-sessions/01f82af583faea102a7ea130ceaad3d4.json +0 -9
  294. package/memory/update-set-sessions/27718fb983faea102a7ea130ceaad34b.json +0 -9
  295. package/memory/update-set-sessions/412e9bf6833e22502a7ea130ceaad30a.json +0 -8
  296. package/memory/update-set-sessions/66fc5a79837aea102a7ea130ceaad3ab.json +0 -9
  297. package/memory/update-set-sessions/71a30ff5837eea102a7ea130ceaad37f.json +0 -9
  298. package/memory/update-set-sessions/74fba27983faea102a7ea130ceaad3bd.json +0 -9
  299. package/memory/update-set-sessions/a0b147b5837eea102a7ea130ceaad344.json +0 -58
  300. package/memory/update-set-sessions/b13f5eb983baea102a7ea130ceaad33e.json +0 -9
  301. package/reports/swarm-auto-centralized-1752649029776.json +0 -13
  302. package/src/memory/README.md +0 -240
@@ -1,1488 +0,0 @@
1
- "use strict";
2
- /**
3
- * Comprehensive Error Handling and Rollback System
4
- * Advanced error handling with automatic rollback capabilities
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.FlowErrorHandler = exports.ErrorSeverity = exports.ErrorType = void 0;
8
- const logger_js_1 = require("../utils/logger.js");
9
- var ErrorType;
10
- (function (ErrorType) {
11
- ErrorType["VALIDATION_ERROR"] = "validation_error";
12
- ErrorType["API_ERROR"] = "api_error";
13
- ErrorType["AUTHENTICATION_ERROR"] = "authentication_error";
14
- ErrorType["AUTHORIZATION_ERROR"] = "authorization_error";
15
- ErrorType["NETWORK_ERROR"] = "network_error";
16
- ErrorType["TIMEOUT_ERROR"] = "timeout_error";
17
- ErrorType["RATE_LIMIT_ERROR"] = "rate_limit_error";
18
- ErrorType["RESOURCE_NOT_FOUND"] = "resource_not_found";
19
- ErrorType["CONFLICT_ERROR"] = "conflict_error";
20
- ErrorType["SERVICE_UNAVAILABLE"] = "service_unavailable";
21
- ErrorType["FLOW_LOGIC_ERROR"] = "flow_logic_error";
22
- ErrorType["ROLLBACK_ERROR"] = "rollback_error";
23
- ErrorType["UNKNOWN_ERROR"] = "unknown_error";
24
- })(ErrorType || (exports.ErrorType = ErrorType = {}));
25
- var ErrorSeverity;
26
- (function (ErrorSeverity) {
27
- ErrorSeverity["CRITICAL"] = "critical";
28
- ErrorSeverity["HIGH"] = "high";
29
- ErrorSeverity["MEDIUM"] = "medium";
30
- ErrorSeverity["LOW"] = "low";
31
- })(ErrorSeverity || (exports.ErrorSeverity = ErrorSeverity = {}));
32
- class FlowErrorHandler {
33
- constructor(client) {
34
- this.transactions = new Map();
35
- this.errorHistory = [];
36
- this.maxErrorHistory = 1000;
37
- this.retryDelays = [1000, 2000, 5000, 10000, 30000]; // Exponential backoff
38
- this.client = client;
39
- this.logger = new logger_js_1.Logger('FlowErrorHandler');
40
- }
41
- /**
42
- * Handle an error with automatic recovery
43
- */
44
- async handleError(error, context) {
45
- const flowError = this.classifyError(error, context);
46
- this.errorHistory.push(flowError);
47
- // Limit error history size
48
- if (this.errorHistory.length > this.maxErrorHistory) {
49
- this.errorHistory.shift();
50
- }
51
- this.logger.error('Flow error occurred', {
52
- type: flowError.type,
53
- severity: flowError.severity,
54
- message: flowError.message,
55
- context: flowError.context
56
- });
57
- // Determine recovery strategy
58
- const recoveryActions = this.determineRecoveryActions(flowError);
59
- const result = {
60
- success: false,
61
- recovered: false,
62
- actions_taken: []
63
- };
64
- // Execute recovery actions
65
- for (const action of recoveryActions) {
66
- try {
67
- const actionResult = await this.executeRecoveryAction(action, flowError);
68
- result.actions_taken.push(action);
69
- if (actionResult.success) {
70
- result.success = true;
71
- result.recovered = true;
72
- result.final_state = actionResult.final_state;
73
- break;
74
- }
75
- }
76
- catch (recoveryError) {
77
- this.logger.error('Recovery action failed', {
78
- action: action.type,
79
- error: recoveryError
80
- });
81
- }
82
- }
83
- // Generate user-friendly message
84
- result.user_message = this.generateUserMessage(flowError, result);
85
- result.technical_details = this.generateTechnicalDetails(flowError, result);
86
- return result;
87
- }
88
- /**
89
- * Start a new transaction
90
- */
91
- startTransaction(flowId) {
92
- const transactionId = this.generateTransactionId();
93
- const transaction = {
94
- id: transactionId,
95
- flow_id: flowId,
96
- operations: [],
97
- status: 'active',
98
- start_time: new Date(),
99
- checkpoints: []
100
- };
101
- this.transactions.set(transactionId, transaction);
102
- this.logger.info('Transaction started', { transactionId, flowId });
103
- return transactionId;
104
- }
105
- /**
106
- * Add operation to transaction
107
- */
108
- addOperation(transactionId, operation) {
109
- const transaction = this.transactions.get(transactionId);
110
- if (!transaction) {
111
- throw new Error(`Transaction ${transactionId} not found`);
112
- }
113
- const rollbackOperation = {
114
- ...operation,
115
- id: this.generateOperationId(),
116
- timestamp: new Date()
117
- };
118
- transaction.operations.push(rollbackOperation);
119
- this.logger.debug('Operation added to transaction', { transactionId, operationId: rollbackOperation.id });
120
- }
121
- /**
122
- * Create checkpoint in transaction
123
- */
124
- createCheckpoint(transactionId, description) {
125
- const transaction = this.transactions.get(transactionId);
126
- if (!transaction) {
127
- throw new Error(`Transaction ${transactionId} not found`);
128
- }
129
- const checkpoint = {
130
- id: this.generateCheckpointId(),
131
- timestamp: new Date(),
132
- operation_count: transaction.operations.length,
133
- state_snapshot: this.captureStateSnapshot(transaction),
134
- description
135
- };
136
- transaction.checkpoints.push(checkpoint);
137
- this.logger.info('Checkpoint created', { transactionId, checkpointId: checkpoint.id, description });
138
- return checkpoint.id;
139
- }
140
- /**
141
- * Commit transaction
142
- */
143
- async commitTransaction(transactionId) {
144
- const transaction = this.transactions.get(transactionId);
145
- if (!transaction) {
146
- throw new Error(`Transaction ${transactionId} not found`);
147
- }
148
- transaction.status = 'committed';
149
- transaction.end_time = new Date();
150
- this.logger.info('Transaction committed', {
151
- transactionId,
152
- operationCount: transaction.operations.length,
153
- duration: transaction.end_time.getTime() - transaction.start_time.getTime()
154
- });
155
- // Clean up transaction after some time
156
- setTimeout(() => {
157
- this.transactions.delete(transactionId);
158
- }, 300000); // 5 minutes
159
- }
160
- /**
161
- * Rollback transaction
162
- */
163
- async rollbackTransaction(transactionId, toCheckpoint) {
164
- const transaction = this.transactions.get(transactionId);
165
- if (!transaction) {
166
- throw new Error(`Transaction ${transactionId} not found`);
167
- }
168
- this.logger.info('Starting transaction rollback', { transactionId, toCheckpoint });
169
- let operationsToRollback = transaction.operations.slice();
170
- // If rolling back to a checkpoint, only rollback operations after that checkpoint
171
- if (toCheckpoint) {
172
- const checkpoint = transaction.checkpoints.find(cp => cp.id === toCheckpoint);
173
- if (checkpoint) {
174
- operationsToRollback = transaction.operations.slice(checkpoint.operation_count);
175
- }
176
- }
177
- // Rollback operations in reverse order
178
- operationsToRollback.reverse();
179
- const rollbackErrors = [];
180
- for (const operation of operationsToRollback) {
181
- try {
182
- await this.rollbackOperation(operation);
183
- this.logger.debug('Operation rolled back', { operationId: operation.id });
184
- }
185
- catch (error) {
186
- rollbackErrors.push(error instanceof Error ? error : new Error(String(error)));
187
- this.logger.error('Rollback operation failed', { operationId: operation.id, error });
188
- }
189
- }
190
- transaction.status = rollbackErrors.length > 0 ? 'failed' : 'rolled_back';
191
- transaction.end_time = new Date();
192
- if (rollbackErrors.length > 0) {
193
- throw new Error(`Rollback failed with ${rollbackErrors.length} errors: ${rollbackErrors.map(e => e.message).join(', ')}`);
194
- }
195
- this.logger.info('Transaction rollback completed', { transactionId });
196
- }
197
- /**
198
- * Rollback a single operation
199
- */
200
- async rollbackOperation(operation) {
201
- switch (operation.type) {
202
- case 'create':
203
- // Delete the created record
204
- if (operation.record_id) {
205
- await this.client.deleteRecord(operation.table, operation.record_id);
206
- }
207
- break;
208
- case 'update':
209
- // Restore original data
210
- if (operation.record_id && operation.original_data) {
211
- await this.client.updateRecord(operation.table, operation.record_id, operation.original_data);
212
- }
213
- break;
214
- case 'delete':
215
- // Recreate the deleted record
216
- if (operation.original_data) {
217
- await this.client.createRecord(operation.table, operation.original_data);
218
- }
219
- break;
220
- }
221
- // Execute custom rollback function if provided
222
- if (operation.rollback_function) {
223
- await operation.rollback_function();
224
- }
225
- }
226
- /**
227
- * Classify error type and severity
228
- */
229
- classifyError(error, context) {
230
- let type = ErrorType.UNKNOWN_ERROR;
231
- let severity = ErrorSeverity.MEDIUM;
232
- let recoverable = true;
233
- let suggestedActions = [];
234
- const errorMessage = error.message.toLowerCase();
235
- // Classify by error message patterns
236
- if (errorMessage.includes('validation') || errorMessage.includes('invalid')) {
237
- type = ErrorType.VALIDATION_ERROR;
238
- severity = ErrorSeverity.HIGH;
239
- suggestedActions = [
240
- { type: 'fallback', description: 'Use fallback values', priority: 'high' },
241
- { type: 'notify', description: 'Notify user of validation issues', priority: 'medium' }
242
- ];
243
- }
244
- else if (errorMessage.includes('unauthorized') || errorMessage.includes('authentication')) {
245
- type = ErrorType.AUTHENTICATION_ERROR;
246
- severity = ErrorSeverity.CRITICAL;
247
- recoverable = false;
248
- suggestedActions = [
249
- { type: 'notify', description: 'Request user to re-authenticate', priority: 'high' }
250
- ];
251
- }
252
- else if (errorMessage.includes('forbidden') || errorMessage.includes('access denied')) {
253
- type = ErrorType.AUTHORIZATION_ERROR;
254
- severity = ErrorSeverity.HIGH;
255
- recoverable = false;
256
- suggestedActions = [
257
- { type: 'notify', description: 'Inform user of insufficient permissions', priority: 'high' }
258
- ];
259
- }
260
- else if (errorMessage.includes('network') || errorMessage.includes('connection')) {
261
- type = ErrorType.NETWORK_ERROR;
262
- severity = ErrorSeverity.MEDIUM;
263
- suggestedActions = [
264
- { type: 'retry', description: 'Retry with exponential backoff', priority: 'high' },
265
- { type: 'fallback', description: 'Use cached data if available', priority: 'medium' }
266
- ];
267
- }
268
- else if (errorMessage.includes('timeout')) {
269
- type = ErrorType.TIMEOUT_ERROR;
270
- severity = ErrorSeverity.MEDIUM;
271
- suggestedActions = [
272
- { type: 'retry', description: 'Retry with increased timeout', priority: 'high' }
273
- ];
274
- }
275
- else if (errorMessage.includes('rate limit') || errorMessage.includes('too many requests')) {
276
- type = ErrorType.RATE_LIMIT_ERROR;
277
- severity = ErrorSeverity.LOW;
278
- suggestedActions = [
279
- { type: 'retry', description: 'Retry after delay', priority: 'high', parameters: { delay: 60000 } }
280
- ];
281
- }
282
- else if (errorMessage.includes('not found') || errorMessage.includes('404')) {
283
- type = ErrorType.RESOURCE_NOT_FOUND;
284
- severity = ErrorSeverity.HIGH;
285
- suggestedActions = [
286
- { type: 'fallback', description: 'Create missing resource', priority: 'high' },
287
- { type: 'notify', description: 'Inform user of missing resource', priority: 'medium' }
288
- ];
289
- }
290
- else if (errorMessage.includes('conflict') || errorMessage.includes('409')) {
291
- type = ErrorType.CONFLICT_ERROR;
292
- severity = ErrorSeverity.MEDIUM;
293
- suggestedActions = [
294
- { type: 'retry', description: 'Retry after resolving conflict', priority: 'high' },
295
- { type: 'fallback', description: 'Use alternative approach', priority: 'medium' }
296
- ];
297
- }
298
- else if (errorMessage.includes('service unavailable') || errorMessage.includes('503')) {
299
- type = ErrorType.SERVICE_UNAVAILABLE;
300
- severity = ErrorSeverity.HIGH;
301
- suggestedActions = [
302
- { type: 'retry', description: 'Retry after service recovery', priority: 'high' },
303
- { type: 'notify', description: 'Inform user of service unavailability', priority: 'medium' }
304
- ];
305
- }
306
- // Determine if rollback is needed
307
- if (context.flow_id && ['create', 'update', 'delete'].includes(context.operation)) {
308
- suggestedActions.unshift({
309
- type: 'rollback',
310
- description: 'Rollback partial changes',
311
- priority: 'high'
312
- });
313
- }
314
- return {
315
- type,
316
- severity,
317
- message: error.message,
318
- context,
319
- original_error: error,
320
- recoverable,
321
- suggested_actions: suggestedActions,
322
- retry_count: 0,
323
- max_retries: this.getMaxRetries(type)
324
- };
325
- }
326
- /**
327
- * Determine recovery actions based on error
328
- */
329
- determineRecoveryActions(error) {
330
- const actions = [];
331
- // Sort suggested actions by priority
332
- const sortedActions = error.suggested_actions.sort((a, b) => {
333
- const priorityOrder = { high: 3, medium: 2, low: 1 };
334
- return priorityOrder[b.priority] - priorityOrder[a.priority];
335
- });
336
- // Add retry logic for recoverable errors
337
- if (error.recoverable && error.retry_count < error.max_retries) {
338
- actions.push({
339
- type: 'retry',
340
- description: `Retry operation (attempt ${error.retry_count + 1}/${error.max_retries})`,
341
- priority: 'high',
342
- parameters: {
343
- delay: this.retryDelays[Math.min(error.retry_count, this.retryDelays.length - 1)]
344
- }
345
- });
346
- }
347
- // Add suggested actions
348
- actions.push(...sortedActions);
349
- return actions;
350
- }
351
- /**
352
- * Execute a recovery action
353
- */
354
- async executeRecoveryAction(action, error) {
355
- switch (action.type) {
356
- case 'retry':
357
- return await this.executeRetry(action, error);
358
- case 'rollback':
359
- return await this.executeRollback(action, error);
360
- case 'fallback':
361
- return await this.executeFallback(action, error);
362
- case 'skip':
363
- return await this.executeSkip(action, error);
364
- case 'notify':
365
- return await this.executeNotify(action, error);
366
- default:
367
- return { success: false };
368
- }
369
- }
370
- /**
371
- * Execute retry action
372
- */
373
- async executeRetry(action, error) {
374
- const delay = action.parameters?.delay || 1000;
375
- this.logger.info('Executing retry', { delay, retryCount: error.retry_count });
376
- // Wait before retry
377
- await new Promise(resolve => setTimeout(resolve, delay));
378
- try {
379
- // Retry the original operation
380
- const result = await this.retryOriginalOperation(error);
381
- return { success: true, final_state: result };
382
- }
383
- catch (retryError) {
384
- error.retry_count = (error.retry_count || 0) + 1;
385
- return { success: false };
386
- }
387
- }
388
- /**
389
- * Execute rollback action
390
- */
391
- async executeRollback(action, error) {
392
- if (!error.context.flow_id) {
393
- return { success: false };
394
- }
395
- // Find transaction for this flow
396
- const transaction = Array.from(this.transactions.values())
397
- .find(t => t.flow_id === error.context.flow_id && t.status === 'active');
398
- if (!transaction) {
399
- return { success: false };
400
- }
401
- try {
402
- await this.rollbackTransaction(transaction.id);
403
- return { success: true, final_state: 'rolled_back' };
404
- }
405
- catch (rollbackError) {
406
- return { success: false };
407
- }
408
- }
409
- /**
410
- * Execute fallback action
411
- */
412
- async executeFallback(action, error) {
413
- // Implement fallback logic based on error type
414
- switch (error.type) {
415
- case ErrorType.RESOURCE_NOT_FOUND:
416
- return await this.createMissingResource(error);
417
- case ErrorType.VALIDATION_ERROR:
418
- return await this.useFallbackValues(error);
419
- case ErrorType.NETWORK_ERROR:
420
- return await this.useCachedData(error);
421
- default:
422
- return { success: false };
423
- }
424
- }
425
- /**
426
- * Execute skip action
427
- */
428
- async executeSkip(action, error) {
429
- this.logger.info('Skipping failed operation', { error: error.type });
430
- return { success: true, final_state: 'skipped' };
431
- }
432
- /**
433
- * Execute notify action
434
- */
435
- async executeNotify(action, error) {
436
- // Create notification record
437
- try {
438
- await this.client.createRecord('sys_email', {
439
- to: 'admin@company.com',
440
- subject: `Flow Error: ${error.type}`,
441
- body: `An error occurred in flow operation: ${error.message}`
442
- });
443
- return { success: true, final_state: 'notified' };
444
- }
445
- catch (notifyError) {
446
- return { success: false };
447
- }
448
- }
449
- /**
450
- * Retry original operation with exponential backoff
451
- */
452
- async retryOriginalOperation(error) {
453
- const maxRetries = error.max_retries || 3;
454
- const currentRetryCount = error.retry_count || 0;
455
- this.logger.info(`Attempting retry ${currentRetryCount + 1}/${maxRetries} for operation`, {
456
- operation: error.context.operation,
457
- error_type: error.type,
458
- previous_attempts: currentRetryCount
459
- });
460
- // Check if we've exceeded max retries
461
- if (currentRetryCount >= maxRetries) {
462
- this.logger.error('Maximum retry attempts exceeded', {
463
- operation: error.context.operation,
464
- total_attempts: currentRetryCount,
465
- final_error: error.message
466
- });
467
- return {
468
- success: false,
469
- final_state: null,
470
- retry_exhausted: true,
471
- total_attempts: currentRetryCount,
472
- last_error: error.message,
473
- suggested_actions: [
474
- 'Review the operation configuration',
475
- 'Check ServiceNow system status',
476
- 'Contact administrator for manual intervention',
477
- 'Consider alternative approach'
478
- ]
479
- };
480
- }
481
- // Calculate retry delay using exponential backoff
482
- const baseDelay = this.retryDelays[Math.min(currentRetryCount, this.retryDelays.length - 1)];
483
- const jitterDelay = baseDelay + Math.random() * 1000; // Add jitter to prevent thundering herd
484
- this.logger.info(`Waiting ${Math.round(jitterDelay)}ms before retry attempt`, {
485
- retry_count: currentRetryCount + 1,
486
- base_delay: baseDelay,
487
- actual_delay: Math.round(jitterDelay)
488
- });
489
- // Wait before retry
490
- await this.delay(jitterDelay);
491
- try {
492
- // Determine retry strategy based on error type
493
- const retryResult = await this.executeRetryBasedOnErrorType(error);
494
- if (retryResult.success) {
495
- this.logger.info('Retry attempt successful', {
496
- operation: error.context.operation,
497
- retry_count: currentRetryCount + 1,
498
- success_after_attempts: currentRetryCount + 1
499
- });
500
- return {
501
- success: true,
502
- final_state: retryResult.data,
503
- retry_count: currentRetryCount + 1,
504
- recovery_method: 'retry_with_backoff'
505
- };
506
- }
507
- else {
508
- // Update error with new retry count and continue retry cycle
509
- const updatedError = {
510
- ...error,
511
- retry_count: currentRetryCount + 1,
512
- message: retryResult.error || error.message
513
- };
514
- // Recursively retry if not at max attempts
515
- return await this.retryOriginalOperation(updatedError);
516
- }
517
- }
518
- catch (retryError) {
519
- this.logger.error('Error during retry attempt', {
520
- retry_count: currentRetryCount + 1,
521
- error: retryError instanceof Error ? retryError.message : String(retryError)
522
- });
523
- // Create updated error for next retry or final failure
524
- const updatedError = {
525
- ...error,
526
- retry_count: currentRetryCount + 1,
527
- message: retryError instanceof Error ? retryError.message : String(retryError),
528
- original_error: retryError instanceof Error ? retryError : new Error(String(retryError))
529
- };
530
- // Continue retry cycle
531
- return await this.retryOriginalOperation(updatedError);
532
- }
533
- }
534
- /**
535
- * Execute retry based on specific error type
536
- */
537
- async executeRetryBasedOnErrorType(error) {
538
- try {
539
- switch (error.type) {
540
- case ErrorType.AUTHENTICATION_ERROR:
541
- return await this.retryAuthenticationOperation(error);
542
- case ErrorType.NETWORK_ERROR:
543
- case ErrorType.TIMEOUT_ERROR:
544
- return await this.retryNetworkOperation(error);
545
- case ErrorType.RATE_LIMIT_ERROR:
546
- return await this.retryRateLimitedOperation(error);
547
- case ErrorType.SERVICE_UNAVAILABLE:
548
- return await this.retryServiceUnavailableOperation(error);
549
- case ErrorType.API_ERROR:
550
- return await this.retryAPIOperation(error);
551
- case ErrorType.CONFLICT_ERROR:
552
- return await this.retryConflictOperation(error);
553
- case ErrorType.RESOURCE_NOT_FOUND:
554
- return await this.retryResourceOperation(error);
555
- default:
556
- return await this.retryGenericOperation(error);
557
- }
558
- }
559
- catch (executeError) {
560
- return {
561
- success: false,
562
- error: executeError instanceof Error ? executeError.message : String(executeError)
563
- };
564
- }
565
- }
566
- /**
567
- * Retry authentication operations
568
- */
569
- async retryAuthenticationOperation(error) {
570
- try {
571
- this.logger.info('Retrying authentication operation');
572
- // Try to refresh authentication
573
- const credentials = this.client.credentialsInstance;
574
- if (credentials?.refreshToken) {
575
- // Attempt token refresh
576
- const refreshResult = await this.client.oauth?.refreshAccessToken();
577
- if (refreshResult?.success) {
578
- // Retry the original operation with new token
579
- return await this.retryWithNewAuthentication(error);
580
- }
581
- }
582
- return {
583
- success: false,
584
- error: 'Authentication refresh failed - manual re-authentication required'
585
- };
586
- }
587
- catch (authError) {
588
- return {
589
- success: false,
590
- error: authError instanceof Error ? authError.message : String(authError)
591
- };
592
- }
593
- }
594
- /**
595
- * Retry network operations
596
- */
597
- async retryNetworkOperation(error) {
598
- try {
599
- this.logger.info('Retrying network operation');
600
- // For network errors, simply retry the original request
601
- return await this.executeOriginalOperation(error);
602
- }
603
- catch (networkError) {
604
- return {
605
- success: false,
606
- error: networkError instanceof Error ? networkError.message : String(networkError)
607
- };
608
- }
609
- }
610
- /**
611
- * Retry rate limited operations with longer delay
612
- */
613
- async retryRateLimitedOperation(error) {
614
- try {
615
- this.logger.info('Retrying rate limited operation with extended delay');
616
- // Rate limit errors need longer delays
617
- const rateLimitDelay = 30000 + Math.random() * 10000; // 30-40 seconds
618
- await this.delay(rateLimitDelay);
619
- return await this.executeOriginalOperation(error);
620
- }
621
- catch (rateLimitError) {
622
- return {
623
- success: false,
624
- error: rateLimitError instanceof Error ? rateLimitError.message : String(rateLimitError)
625
- };
626
- }
627
- }
628
- /**
629
- * Retry service unavailable operations
630
- */
631
- async retryServiceUnavailableOperation(error) {
632
- try {
633
- this.logger.info('Retrying operation after service unavailability');
634
- // Check service health before retry
635
- const healthCheck = await this.performServiceHealthCheck();
636
- if (!healthCheck.healthy) {
637
- return {
638
- success: false,
639
- error: `Service still unavailable: ${healthCheck.reason}`
640
- };
641
- }
642
- return await this.executeOriginalOperation(error);
643
- }
644
- catch (serviceError) {
645
- return {
646
- success: false,
647
- error: serviceError instanceof Error ? serviceError.message : String(serviceError)
648
- };
649
- }
650
- }
651
- /**
652
- * Retry API operations
653
- */
654
- async retryAPIOperation(error) {
655
- try {
656
- this.logger.info('Retrying API operation');
657
- // API errors might be transient, retry with same parameters
658
- return await this.executeOriginalOperation(error);
659
- }
660
- catch (apiError) {
661
- return {
662
- success: false,
663
- error: apiError instanceof Error ? apiError.message : String(apiError)
664
- };
665
- }
666
- }
667
- /**
668
- * Retry conflict operations with modified data
669
- */
670
- async retryConflictOperation(error) {
671
- try {
672
- this.logger.info('Retrying conflict operation with modifications');
673
- // For conflicts, try to modify the operation slightly
674
- const modifiedOperation = await this.modifyOperationForConflictResolution(error);
675
- return await this.executeModifiedOperation(error, modifiedOperation);
676
- }
677
- catch (conflictError) {
678
- return {
679
- success: false,
680
- error: conflictError instanceof Error ? conflictError.message : String(conflictError)
681
- };
682
- }
683
- }
684
- /**
685
- * Retry resource operations
686
- */
687
- async retryResourceOperation(error) {
688
- try {
689
- this.logger.info('Retrying resource operation');
690
- // For resource not found, try to create the resource first
691
- const resourceCreated = await this.ensureResourceExists(error);
692
- if (resourceCreated.success) {
693
- return await this.executeOriginalOperation(error);
694
- }
695
- return {
696
- success: false,
697
- error: `Failed to create required resource: ${resourceCreated.error}`
698
- };
699
- }
700
- catch (resourceError) {
701
- return {
702
- success: false,
703
- error: resourceError instanceof Error ? resourceError.message : String(resourceError)
704
- };
705
- }
706
- }
707
- /**
708
- * Generic retry operation
709
- */
710
- async retryGenericOperation(error) {
711
- try {
712
- this.logger.info('Performing generic retry operation');
713
- // Generic retry - just execute the original operation again
714
- return await this.executeOriginalOperation(error);
715
- }
716
- catch (genericError) {
717
- return {
718
- success: false,
719
- error: genericError instanceof Error ? genericError.message : String(genericError)
720
- };
721
- }
722
- }
723
- /**
724
- * Execute the original operation that failed
725
- */
726
- async executeOriginalOperation(error) {
727
- try {
728
- // This would reconstruct and execute the original operation
729
- // For now, we'll simulate the operation based on context
730
- const operation = error.context.operation;
731
- const operationType = this.extractOperationType(operation);
732
- switch (operationType) {
733
- case 'deploy':
734
- return await this.retryDeployOperation(error);
735
- case 'search':
736
- return await this.retrySearchOperation(error);
737
- case 'create':
738
- return await this.retryCreateOperation(error);
739
- case 'update':
740
- return await this.retryUpdateOperation(error);
741
- default:
742
- // Generic HTTP request retry
743
- return await this.retryHTTPRequest(error);
744
- }
745
- }
746
- catch (executeError) {
747
- return {
748
- success: false,
749
- error: executeError instanceof Error ? executeError.message : String(executeError)
750
- };
751
- }
752
- }
753
- // Helper methods for specific operation types
754
- async retryDeployOperation(error) {
755
- try {
756
- this.logger.info('Retrying deployment operation', {
757
- component_type: error.context.component_type,
758
- component_id: error.context.component_id
759
- });
760
- // Extract deployment parameters from context
761
- const deploymentData = error.context.user_input;
762
- if (!deploymentData) {
763
- return { success: false, error: 'No deployment data available for retry' };
764
- }
765
- // Retry based on component type
766
- switch (error.context.component_type) {
767
- case 'widget':
768
- return await this.retryWidgetDeployment(deploymentData, error);
769
- case 'flow':
770
- return await this.retryFlowDeployment(deploymentData, error);
771
- case 'application':
772
- return await this.retryApplicationDeployment(deploymentData, error);
773
- case 'script':
774
- return await this.retryScriptDeployment(deploymentData, error);
775
- default:
776
- return await this.retryGenericDeployment(deploymentData, error);
777
- }
778
- }
779
- catch (deployError) {
780
- return {
781
- success: false,
782
- error: deployError instanceof Error ? deployError.message : String(deployError)
783
- };
784
- }
785
- }
786
- async retrySearchOperation(error) {
787
- try {
788
- this.logger.info('Retrying search operation', { operation: error.context.operation });
789
- const searchParams = error.context.user_input;
790
- if (!searchParams) {
791
- return { success: false, error: 'No search parameters available for retry' };
792
- }
793
- // Modify search parameters if this is a retry to avoid same failure
794
- const modifiedParams = {
795
- ...searchParams,
796
- sysparm_limit: Math.min(searchParams.sysparm_limit || 100, 50), // Reduce limit
797
- sysparm_offset: searchParams.sysparm_offset || 0,
798
- retry_attempt: (error.retry_count || 0) + 1
799
- };
800
- // Perform the search request
801
- const result = await this.client.makeRequest({
802
- method: 'GET',
803
- endpoint: searchParams.endpoint || '/api/now/table/sys_metadata',
804
- params: modifiedParams
805
- });
806
- if (result.status === 200) {
807
- return { success: true, data: result.data };
808
- }
809
- else {
810
- return { success: false, error: `Search failed with status: ${result.status}` };
811
- }
812
- }
813
- catch (searchError) {
814
- return {
815
- success: false,
816
- error: searchError instanceof Error ? searchError.message : String(searchError)
817
- };
818
- }
819
- }
820
- async retryCreateOperation(error) {
821
- try {
822
- this.logger.info('Retrying create operation', {
823
- table: error.context.component_type,
824
- retry_count: error.retry_count
825
- });
826
- const createData = error.context.user_input;
827
- if (!createData || !createData.table) {
828
- return { success: false, error: 'No create data or table specified for retry' };
829
- }
830
- // Modify data for conflict resolution if needed
831
- const retryData = { ...createData.data };
832
- // If this is a conflict retry, modify unique fields
833
- if (error.type === ErrorType.CONFLICT_ERROR && error.retry_count > 0) {
834
- const timestamp = Date.now();
835
- if (retryData.name) {
836
- retryData.name = `${retryData.name}_retry_${timestamp}`;
837
- }
838
- if (retryData.sys_name) {
839
- retryData.sys_name = `${retryData.sys_name}_retry_${timestamp}`;
840
- }
841
- }
842
- // Perform the create request
843
- const result = await this.client.createRecord(createData.table, retryData);
844
- if (result && result.sys_id) {
845
- this.logger.info('Create operation retry successful', { sys_id: result.sys_id });
846
- return { success: true, data: result };
847
- }
848
- else {
849
- return { success: false, error: 'Create operation failed - no sys_id returned' };
850
- }
851
- }
852
- catch (createError) {
853
- return {
854
- success: false,
855
- error: createError instanceof Error ? createError.message : String(createError)
856
- };
857
- }
858
- }
859
- async retryUpdateOperation(error) {
860
- try {
861
- this.logger.info('Retrying update operation', {
862
- table: error.context.component_type,
863
- record_id: error.context.component_id
864
- });
865
- const updateData = error.context.user_input;
866
- if (!updateData || !updateData.table || !updateData.record_id) {
867
- return { success: false, error: 'No update data, table, or record ID available for retry' };
868
- }
869
- // First, verify the record still exists
870
- try {
871
- const existingRecord = await this.client.getRecord(updateData.table, updateData.record_id);
872
- if (!existingRecord) {
873
- return { success: false, error: 'Record no longer exists for update' };
874
- }
875
- }
876
- catch (getError) {
877
- return { success: false, error: 'Cannot verify record existence for update retry' };
878
- }
879
- // Perform the update request
880
- const result = await this.client.updateRecord(updateData.table, updateData.record_id, updateData.data);
881
- if (result) {
882
- this.logger.info('Update operation retry successful', { sys_id: updateData.record_id });
883
- return { success: true, data: result };
884
- }
885
- else {
886
- return { success: false, error: 'Update operation failed' };
887
- }
888
- }
889
- catch (updateError) {
890
- return {
891
- success: false,
892
- error: updateError instanceof Error ? updateError.message : String(updateError)
893
- };
894
- }
895
- }
896
- async retryHTTPRequest(error) {
897
- try {
898
- this.logger.info('Retrying HTTP request', { operation: error.context.operation });
899
- const requestData = error.context.user_input;
900
- if (!requestData) {
901
- return { success: false, error: 'No request data available for HTTP retry' };
902
- }
903
- // Construct request with retry-safe parameters
904
- const requestConfig = {
905
- method: requestData.method || 'GET',
906
- endpoint: requestData.endpoint || requestData.url,
907
- params: requestData.params,
908
- data: requestData.data,
909
- timeout: Math.min((requestData.timeout || 30000) * 1.5, 60000), // Increase timeout
910
- retry_attempt: (error.retry_count || 0) + 1
911
- };
912
- // Add retry headers
913
- const headers = {
914
- ...requestData.headers,
915
- 'X-Retry-Attempt': String(requestConfig.retry_attempt),
916
- 'X-Request-ID': `retry_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
917
- };
918
- const result = await this.client.makeRequest({
919
- ...requestConfig,
920
- headers
921
- });
922
- if (result.status >= 200 && result.status < 300) {
923
- return { success: true, data: result.data };
924
- }
925
- else {
926
- return {
927
- success: false,
928
- error: `HTTP request failed with status: ${result.status} - ${result.statusText}`
929
- };
930
- }
931
- }
932
- catch (httpError) {
933
- return {
934
- success: false,
935
- error: httpError instanceof Error ? httpError.message : String(httpError)
936
- };
937
- }
938
- }
939
- // Additional helper methods
940
- async retryWithNewAuthentication(error) {
941
- // Retry with refreshed authentication
942
- return await this.executeOriginalOperation(error);
943
- }
944
- async performServiceHealthCheck() {
945
- try {
946
- // Basic health check - try to access ServiceNow instance
947
- const response = await this.client.makeRequest({
948
- method: 'GET',
949
- endpoint: '/api/now/v2/table/sys_user',
950
- params: { sysparm_limit: 1 }
951
- });
952
- return { healthy: response.status === 200 };
953
- }
954
- catch (healthError) {
955
- return {
956
- healthy: false,
957
- reason: healthError instanceof Error ? healthError.message : 'Unknown health check error'
958
- };
959
- }
960
- }
961
- async modifyOperationForConflictResolution(error) {
962
- // Modify operation to resolve conflicts (e.g., add timestamp to name)
963
- const timestamp = Date.now();
964
- return {
965
- ...error.context.system_state,
966
- name: `${error.context.system_state?.name || 'item'}_${timestamp}`,
967
- modified_for_conflict: true
968
- };
969
- }
970
- async executeModifiedOperation(error, modifiedData) {
971
- try {
972
- this.logger.info('Executing modified operation for conflict resolution', {
973
- original_operation: error.context.operation,
974
- modifications: modifiedData.modified_for_conflict ? 'conflict_resolution' : 'standard'
975
- });
976
- // Execute the operation with modified data based on operation type
977
- const operationType = this.extractOperationType(error.context.operation);
978
- switch (operationType) {
979
- case 'create':
980
- const table = error.context.component_type || 'sys_metadata';
981
- const result = await this.client.createRecord(table, modifiedData);
982
- return { success: true, data: result };
983
- case 'update':
984
- if (!error.context.component_id) {
985
- return { success: false, error: 'No component ID for update operation' };
986
- }
987
- const updateResult = await this.client.updateRecord(error.context.component_type || 'sys_metadata', error.context.component_id, modifiedData);
988
- return { success: true, data: updateResult };
989
- case 'deploy':
990
- // For deployment operations, use the deployment data structure
991
- return await this.retryGenericDeployment(modifiedData, error);
992
- default:
993
- return { success: false, error: 'Unsupported operation type for modification' };
994
- }
995
- }
996
- catch (executeError) {
997
- return {
998
- success: false,
999
- error: executeError instanceof Error ? executeError.message : String(executeError)
1000
- };
1001
- }
1002
- }
1003
- async ensureResourceExists(error) {
1004
- try {
1005
- this.logger.info('Attempting to create missing resource', {
1006
- resource_type: error.context.component_type,
1007
- resource_id: error.context.component_id
1008
- });
1009
- // Extract resource information from context
1010
- const resourceData = error.context.user_input;
1011
- if (!resourceData) {
1012
- return { success: false, error: 'No resource data available for creation' };
1013
- }
1014
- // Determine resource type and create accordingly
1015
- switch (error.context.component_type) {
1016
- case 'table':
1017
- return await this.createMissingTable(resourceData);
1018
- case 'field':
1019
- return await this.createMissingField(resourceData);
1020
- case 'user':
1021
- return await this.createMissingUser(resourceData);
1022
- case 'group':
1023
- return await this.createMissingGroup(resourceData);
1024
- default:
1025
- // Generic resource creation
1026
- return await this.createGenericResource(resourceData);
1027
- }
1028
- }
1029
- catch (resourceError) {
1030
- return {
1031
- success: false,
1032
- error: resourceError instanceof Error ? resourceError.message : String(resourceError)
1033
- };
1034
- }
1035
- }
1036
- async delay(ms) {
1037
- return new Promise(resolve => setTimeout(resolve, ms));
1038
- }
1039
- /**
1040
- * Create missing resource
1041
- */
1042
- async createMissingResource(error) {
1043
- // Implementation depends on the specific resource type
1044
- return { success: false };
1045
- }
1046
- /**
1047
- * Use fallback values
1048
- */
1049
- async useFallbackValues(error) {
1050
- // Implementation depends on the specific validation error
1051
- return { success: false };
1052
- }
1053
- /**
1054
- * Use cached data
1055
- */
1056
- async useCachedData(error) {
1057
- // Implementation depends on the specific cached data available
1058
- return { success: false };
1059
- }
1060
- /**
1061
- * Generate user-friendly error message
1062
- */
1063
- generateUserMessage(error, result) {
1064
- if (result.recovered) {
1065
- return `The operation encountered an issue but was automatically recovered. ${error.message}`;
1066
- }
1067
- switch (error.type) {
1068
- case ErrorType.AUTHENTICATION_ERROR:
1069
- return 'Authentication failed. Please check your credentials and try again.';
1070
- case ErrorType.AUTHORIZATION_ERROR:
1071
- return 'You do not have permission to perform this operation.';
1072
- case ErrorType.VALIDATION_ERROR:
1073
- return 'The provided data is invalid. Please check your inputs and try again.';
1074
- case ErrorType.NETWORK_ERROR:
1075
- return 'Network connection failed. Please check your connection and try again.';
1076
- case ErrorType.RESOURCE_NOT_FOUND:
1077
- return 'The requested resource was not found. It may have been deleted or moved.';
1078
- default:
1079
- return `An error occurred: ${error.message}`;
1080
- }
1081
- }
1082
- /**
1083
- * Generate technical details
1084
- */
1085
- generateTechnicalDetails(error, result) {
1086
- const details = {
1087
- error_type: error.type,
1088
- severity: error.severity,
1089
- message: error.message,
1090
- context: error.context,
1091
- actions_taken: result.actions_taken.map(a => a.type),
1092
- recovered: result.recovered,
1093
- timestamp: new Date().toISOString()
1094
- };
1095
- return JSON.stringify(details, null, 2);
1096
- }
1097
- /**
1098
- * Get max retries for error type
1099
- */
1100
- getMaxRetries(errorType) {
1101
- switch (errorType) {
1102
- case ErrorType.NETWORK_ERROR:
1103
- case ErrorType.TIMEOUT_ERROR:
1104
- return 3;
1105
- case ErrorType.RATE_LIMIT_ERROR:
1106
- return 2;
1107
- case ErrorType.SERVICE_UNAVAILABLE:
1108
- return 5;
1109
- default:
1110
- return 1;
1111
- }
1112
- }
1113
- /**
1114
- * Capture state snapshot
1115
- */
1116
- captureStateSnapshot(transaction) {
1117
- return {
1118
- transaction_id: transaction.id,
1119
- flow_id: transaction.flow_id,
1120
- operation_count: transaction.operations.length,
1121
- status: transaction.status,
1122
- timestamp: new Date().toISOString()
1123
- };
1124
- }
1125
- /**
1126
- * Generate transaction ID
1127
- */
1128
- generateTransactionId() {
1129
- return `tx_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1130
- }
1131
- /**
1132
- * Generate operation ID
1133
- */
1134
- generateOperationId() {
1135
- return `op_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1136
- }
1137
- /**
1138
- * Generate checkpoint ID
1139
- */
1140
- generateCheckpointId() {
1141
- return `cp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1142
- }
1143
- /**
1144
- * Get error statistics
1145
- */
1146
- getErrorStatistics() {
1147
- const stats = {
1148
- total_errors: this.errorHistory.length,
1149
- errors_by_type: {},
1150
- errors_by_severity: {},
1151
- recovery_rate: 0
1152
- };
1153
- let recoveredCount = 0;
1154
- for (const error of this.errorHistory) {
1155
- // Count by type
1156
- stats.errors_by_type[error.type] = (stats.errors_by_type[error.type] || 0) + 1;
1157
- // Count by severity
1158
- stats.errors_by_severity[error.severity] = (stats.errors_by_severity[error.severity] || 0) + 1;
1159
- // Count recovered errors
1160
- if (error.recoverable) {
1161
- recoveredCount++;
1162
- }
1163
- }
1164
- stats.recovery_rate = stats.total_errors > 0 ? recoveredCount / stats.total_errors : 0;
1165
- return stats;
1166
- }
1167
- /**
1168
- * Get active transactions
1169
- */
1170
- getActiveTransactions() {
1171
- return Array.from(this.transactions.values())
1172
- .filter(t => t.status === 'active');
1173
- }
1174
- // =====================================
1175
- // DEPLOYMENT RETRY METHODS
1176
- // =====================================
1177
- /**
1178
- * Retry widget deployment
1179
- */
1180
- async retryWidgetDeployment(deploymentData, error) {
1181
- try {
1182
- this.logger.info('Retrying widget deployment', { widget_name: deploymentData.name });
1183
- // Construct widget data with retry modifications
1184
- const widgetData = {
1185
- name: deploymentData.name,
1186
- title: deploymentData.title,
1187
- template: deploymentData.template,
1188
- server_script: deploymentData.server_script,
1189
- client_script: deploymentData.client_script,
1190
- css: deploymentData.css,
1191
- category: deploymentData.category || 'custom',
1192
- roles: deploymentData.roles || '',
1193
- public: deploymentData.public !== false
1194
- };
1195
- // If this is a conflict retry, modify the name
1196
- if (error.type === ErrorType.CONFLICT_ERROR && (error.retry_count || 0) > 0) {
1197
- widgetData.name = `${widgetData.name}_retry_${Date.now()}`;
1198
- }
1199
- const result = await this.client.createRecord('sp_widget', widgetData);
1200
- return { success: true, data: result };
1201
- }
1202
- catch (widgetError) {
1203
- return {
1204
- success: false,
1205
- error: widgetError instanceof Error ? widgetError.message : String(widgetError)
1206
- };
1207
- }
1208
- }
1209
- /**
1210
- * Retry flow deployment
1211
- */
1212
- async retryFlowDeployment(deploymentData, error) {
1213
- try {
1214
- this.logger.info('Retrying flow deployment', { flow_name: deploymentData.name });
1215
- const flowData = {
1216
- name: deploymentData.name,
1217
- description: deploymentData.description,
1218
- active: deploymentData.active !== false,
1219
- flow_designer: deploymentData.flow_definition || '{}',
1220
- trigger_conditions: deploymentData.trigger_conditions,
1221
- table: deploymentData.table
1222
- };
1223
- // Handle conflict retry
1224
- if (error.type === ErrorType.CONFLICT_ERROR && (error.retry_count || 0) > 0) {
1225
- flowData.name = `${flowData.name}_retry_${Date.now()}`;
1226
- }
1227
- const result = await this.client.createRecord('sys_hub_flow', flowData);
1228
- return { success: true, data: result };
1229
- }
1230
- catch (flowError) {
1231
- return {
1232
- success: false,
1233
- error: flowError instanceof Error ? flowError.message : String(flowError)
1234
- };
1235
- }
1236
- }
1237
- /**
1238
- * Retry application deployment
1239
- */
1240
- async retryApplicationDeployment(deploymentData, error) {
1241
- try {
1242
- this.logger.info('Retrying application deployment', { app_name: deploymentData.name });
1243
- const appData = {
1244
- name: deploymentData.name,
1245
- short_description: deploymentData.short_description,
1246
- description: deploymentData.description,
1247
- version: deploymentData.version || '1.0.0',
1248
- vendor: deploymentData.vendor || 'Custom',
1249
- vendor_prefix: deploymentData.vendor_prefix,
1250
- active: deploymentData.active !== false
1251
- };
1252
- // Handle conflict retry
1253
- if (error.type === ErrorType.CONFLICT_ERROR && (error.retry_count || 0) > 0) {
1254
- appData.name = `${appData.name}_retry_${Date.now()}`;
1255
- }
1256
- const result = await this.client.createRecord('sys_app', appData);
1257
- return { success: true, data: result };
1258
- }
1259
- catch (appError) {
1260
- return {
1261
- success: false,
1262
- error: appError instanceof Error ? appError.message : String(appError)
1263
- };
1264
- }
1265
- }
1266
- /**
1267
- * Retry script deployment
1268
- */
1269
- async retryScriptDeployment(deploymentData, error) {
1270
- try {
1271
- this.logger.info('Retrying script deployment', { script_name: deploymentData.name });
1272
- const scriptData = {
1273
- name: deploymentData.name,
1274
- script: deploymentData.script,
1275
- description: deploymentData.description,
1276
- api_name: deploymentData.api_name,
1277
- client_callable: deploymentData.client_callable || false,
1278
- active: deploymentData.active !== false
1279
- };
1280
- // Handle conflict retry
1281
- if (error.type === ErrorType.CONFLICT_ERROR && (error.retry_count || 0) > 0) {
1282
- scriptData.name = `${scriptData.name}_retry_${Date.now()}`;
1283
- }
1284
- const result = await this.client.createRecord('sys_script_include', scriptData);
1285
- return { success: true, data: result };
1286
- }
1287
- catch (scriptError) {
1288
- return {
1289
- success: false,
1290
- error: scriptError instanceof Error ? scriptError.message : String(scriptError)
1291
- };
1292
- }
1293
- }
1294
- /**
1295
- * Generic deployment retry
1296
- */
1297
- async retryGenericDeployment(deploymentData, error) {
1298
- try {
1299
- this.logger.info('Retrying generic deployment', {
1300
- component_type: error.context.component_type,
1301
- data_keys: Object.keys(deploymentData)
1302
- });
1303
- // Determine table from component type or data
1304
- const table = deploymentData.table ||
1305
- this.getTableFromComponentType(error.context.component_type) ||
1306
- 'sys_metadata';
1307
- const result = await this.client.createRecord(table, deploymentData);
1308
- return { success: true, data: result };
1309
- }
1310
- catch (genericError) {
1311
- return {
1312
- success: false,
1313
- error: genericError instanceof Error ? genericError.message : String(genericError)
1314
- };
1315
- }
1316
- }
1317
- // =====================================
1318
- // RESOURCE CREATION METHODS
1319
- // =====================================
1320
- /**
1321
- * Create missing table
1322
- */
1323
- async createMissingTable(resourceData) {
1324
- try {
1325
- const tableData = {
1326
- name: resourceData.table_name || resourceData.name,
1327
- label: resourceData.label || resourceData.table_name,
1328
- super_class: resourceData.super_class || 'sys_metadata',
1329
- is_extendable: resourceData.is_extendable !== false
1330
- };
1331
- await this.client.createRecord('sys_db_object', tableData);
1332
- return { success: true };
1333
- }
1334
- catch (error) {
1335
- return { success: false, error: error instanceof Error ? error.message : String(error) };
1336
- }
1337
- }
1338
- /**
1339
- * Create missing field
1340
- */
1341
- async createMissingField(resourceData) {
1342
- try {
1343
- const fieldData = {
1344
- table: resourceData.table,
1345
- column_name: resourceData.field_name,
1346
- column_label: resourceData.label || resourceData.field_name,
1347
- internal_type: resourceData.type || 'string',
1348
- max_length: resourceData.max_length || 40
1349
- };
1350
- await this.client.createRecord('sys_dictionary', fieldData);
1351
- return { success: true };
1352
- }
1353
- catch (error) {
1354
- return { success: false, error: error instanceof Error ? error.message : String(error) };
1355
- }
1356
- }
1357
- /**
1358
- * Create missing user
1359
- */
1360
- async createMissingUser(resourceData) {
1361
- try {
1362
- const userData = {
1363
- user_name: resourceData.user_name,
1364
- first_name: resourceData.first_name || 'Unknown',
1365
- last_name: resourceData.last_name || 'User',
1366
- email: resourceData.email,
1367
- active: resourceData.active !== false
1368
- };
1369
- await this.client.createRecord('sys_user', userData);
1370
- return { success: true };
1371
- }
1372
- catch (error) {
1373
- return { success: false, error: error instanceof Error ? error.message : String(error) };
1374
- }
1375
- }
1376
- /**
1377
- * Create missing group
1378
- */
1379
- async createMissingGroup(resourceData) {
1380
- try {
1381
- const groupData = {
1382
- name: resourceData.group_name || resourceData.name,
1383
- description: resourceData.description || `Group ${resourceData.name}`,
1384
- active: resourceData.active !== false
1385
- };
1386
- await this.client.createRecord('sys_user_group', groupData);
1387
- return { success: true };
1388
- }
1389
- catch (error) {
1390
- return { success: false, error: error instanceof Error ? error.message : String(error) };
1391
- }
1392
- }
1393
- /**
1394
- * Create generic resource
1395
- */
1396
- async createGenericResource(resourceData) {
1397
- try {
1398
- const table = resourceData.table || 'sys_metadata';
1399
- await this.client.createRecord(table, resourceData);
1400
- return { success: true };
1401
- }
1402
- catch (error) {
1403
- return { success: false, error: error instanceof Error ? error.message : String(error) };
1404
- }
1405
- }
1406
- // =====================================
1407
- // UTILITY METHODS
1408
- // =====================================
1409
- /**
1410
- * Get ServiceNow table name from component type
1411
- */
1412
- getTableFromComponentType(componentType) {
1413
- if (!componentType)
1414
- return null;
1415
- const tableMap = {
1416
- 'widget': 'sp_widget',
1417
- 'flow': 'sys_hub_flow',
1418
- 'application': 'sys_app',
1419
- 'script': 'sys_script_include',
1420
- 'business_rule': 'sys_script',
1421
- 'client_script': 'sys_script_client',
1422
- 'ui_policy': 'sys_ui_policy',
1423
- 'ui_action': 'sys_ui_action',
1424
- 'table': 'sys_db_object',
1425
- 'field': 'sys_dictionary',
1426
- 'user': 'sys_user',
1427
- 'group': 'sys_user_group'
1428
- };
1429
- return tableMap[componentType.toLowerCase()] || null;
1430
- }
1431
- /**
1432
- * Enhanced operation type extraction
1433
- */
1434
- extractOperationType(operation) {
1435
- const op = operation.toLowerCase();
1436
- // More specific operation detection
1437
- if (op.includes('deploy') || op.includes('create_') || op.includes('snow_deploy'))
1438
- return 'deploy';
1439
- if (op.includes('search') || op.includes('find') || op.includes('query') || op.includes('discover'))
1440
- return 'search';
1441
- if (op.includes('create') || op.includes('insert') || op.includes('add'))
1442
- return 'create';
1443
- if (op.includes('update') || op.includes('modify') || op.includes('edit') || op.includes('patch'))
1444
- return 'update';
1445
- if (op.includes('delete') || op.includes('remove'))
1446
- return 'delete';
1447
- if (op.includes('get') || op.includes('fetch') || op.includes('retrieve'))
1448
- return 'read';
1449
- if (op.includes('authenticate') || op.includes('login') || op.includes('auth'))
1450
- return 'auth';
1451
- if (op.includes('http') || op.includes('request') || op.includes('api'))
1452
- return 'http';
1453
- return 'generic';
1454
- }
1455
- /**
1456
- * Check if error type is retryable
1457
- */
1458
- isRetryableError(errorType) {
1459
- const retryableErrors = [
1460
- ErrorType.NETWORK_ERROR,
1461
- ErrorType.TIMEOUT_ERROR,
1462
- ErrorType.RATE_LIMIT_ERROR,
1463
- ErrorType.SERVICE_UNAVAILABLE,
1464
- ErrorType.API_ERROR,
1465
- ErrorType.CONFLICT_ERROR
1466
- ];
1467
- return retryableErrors.includes(errorType);
1468
- }
1469
- /**
1470
- * Get circuit breaker status for operation
1471
- */
1472
- getCircuitBreakerStatus(operation) {
1473
- // Simple circuit breaker implementation
1474
- const recentErrors = this.errorHistory
1475
- .filter(error => error.context.operation === operation &&
1476
- error.context.timestamp.getTime() > Date.now() - 300000 // Last 5 minutes
1477
- );
1478
- const failureCount = recentErrors.length;
1479
- const isOpen = failureCount >= 5; // Open circuit after 5 failures
1480
- return {
1481
- isOpen,
1482
- failureCount,
1483
- lastFailureTime: recentErrors.length > 0 ? recentErrors[recentErrors.length - 1].context.timestamp : undefined
1484
- };
1485
- }
1486
- }
1487
- exports.FlowErrorHandler = FlowErrorHandler;
1488
- //# sourceMappingURL=error-handling.js.map