@tamyla/clodo-framework 3.1.10 → 3.1.12

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 (86) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/bin/clodo-service-old.js +2 -2
  3. package/dist/bin/commands/create.js +1 -1
  4. package/dist/bin/commands/diagnose.js +1 -1
  5. package/dist/bin/commands/update.js +1 -1
  6. package/dist/bin/commands/validate.js +1 -1
  7. package/dist/bin/database/enterprise-db-manager.js +3 -3
  8. package/dist/bin/deployment/enterprise-deploy.js +3 -3
  9. package/dist/bin/deployment/master-deploy.js +3 -3
  10. package/dist/bin/deployment/modular-enterprise-deploy.js +3 -3
  11. package/dist/bin/deployment/modules/DeploymentOrchestrator.js +1 -1
  12. package/dist/bin/deployment/modules/EnvironmentManager.js +2 -2
  13. package/dist/bin/portfolio/portfolio-manager.js +3 -3
  14. package/dist/bin/security/security-cli.js +1 -1
  15. package/dist/bin/service-management/create-service.js +1 -1
  16. package/dist/bin/service-management/init-service.js +1 -1
  17. package/dist/bin/shared/cloudflare/domain-manager.js +1 -1
  18. package/dist/bin/shared/validation/ValidationRegistry.js +1 -1
  19. package/dist/deployment/wrangler-deployer.js +1 -1
  20. package/dist/orchestration/cross-domain-coordinator.js +5 -5
  21. package/dist/security/index.js +1 -1
  22. package/dist/service-management/ConfirmationEngine.js +1 -1
  23. package/dist/service-management/ErrorTracker.js +1 -1
  24. package/dist/service-management/InputCollector.js +1 -1
  25. package/dist/service-management/ServiceCreator.js +1 -1
  26. package/dist/service-management/ServiceInitializer.js +1 -1
  27. package/dist/utils/config/unified-config-manager.js +1 -1
  28. package/dist/utils/deployment/config-cache.js +1 -1
  29. package/dist/utils/deployment/secret-generator.js +1 -1
  30. package/dist/utils/framework-config.js +1 -1
  31. package/dist/worker/integration.js +1 -1
  32. package/package.json +1 -6
  33. package/bin/README.md +0 -71
  34. package/bin/clodo-service.js +0 -72
  35. package/bin/database/README.md +0 -33
  36. package/bin/database/deployment-db-manager.js +0 -527
  37. package/bin/database/enterprise-db-manager.js +0 -738
  38. package/bin/database/wrangler-d1-manager.js +0 -775
  39. package/bin/security/security-cli.js +0 -117
  40. package/bin/service-management/README.md +0 -74
  41. package/bin/service-management/create-service.js +0 -129
  42. package/bin/service-management/init-service.js +0 -103
  43. package/bin/service-management/init-service.js.backup +0 -889
  44. package/bin/shared/cloudflare/domain-discovery.js +0 -637
  45. package/bin/shared/cloudflare/domain-manager.js +0 -952
  46. package/bin/shared/cloudflare/index.js +0 -8
  47. package/bin/shared/cloudflare/ops.js +0 -401
  48. package/bin/shared/config/ConfigurationManager.js +0 -539
  49. package/bin/shared/config/cache.js +0 -1230
  50. package/bin/shared/config/command-config-manager.js +0 -184
  51. package/bin/shared/config/index.js +0 -21
  52. package/bin/shared/config/manager.js +0 -315
  53. package/bin/shared/database/connection-manager.js +0 -374
  54. package/bin/shared/database/index.js +0 -7
  55. package/bin/shared/database/orchestrator.js +0 -727
  56. package/bin/shared/deployment/auditor.js +0 -970
  57. package/bin/shared/deployment/index.js +0 -10
  58. package/bin/shared/deployment/rollback-manager.js +0 -570
  59. package/bin/shared/deployment/validator.js +0 -779
  60. package/bin/shared/index.js +0 -32
  61. package/bin/shared/logging/Logger.js +0 -214
  62. package/bin/shared/monitoring/health-checker.js +0 -484
  63. package/bin/shared/monitoring/index.js +0 -8
  64. package/bin/shared/monitoring/memory-manager.js +0 -387
  65. package/bin/shared/monitoring/production-monitor.js +0 -403
  66. package/bin/shared/production-tester/api-tester.js +0 -82
  67. package/bin/shared/production-tester/auth-tester.js +0 -132
  68. package/bin/shared/production-tester/core.js +0 -197
  69. package/bin/shared/production-tester/database-tester.js +0 -109
  70. package/bin/shared/production-tester/index.js +0 -77
  71. package/bin/shared/production-tester/load-tester.js +0 -131
  72. package/bin/shared/production-tester/performance-tester.js +0 -103
  73. package/bin/shared/security/api-token-manager.js +0 -312
  74. package/bin/shared/security/index.js +0 -8
  75. package/bin/shared/security/secret-generator.js +0 -942
  76. package/bin/shared/security/secure-token-manager.js +0 -398
  77. package/bin/shared/utils/ErrorHandler.js +0 -675
  78. package/bin/shared/utils/error-recovery.js +0 -245
  79. package/bin/shared/utils/file-manager.js +0 -162
  80. package/bin/shared/utils/formatters.js +0 -247
  81. package/bin/shared/utils/graceful-shutdown-manager.js +0 -390
  82. package/bin/shared/utils/index.js +0 -19
  83. package/bin/shared/utils/interactive-prompts.js +0 -146
  84. package/bin/shared/utils/interactive-utils.js +0 -530
  85. package/bin/shared/utils/rate-limiter.js +0 -246
  86. package/bin/shared/validation/ValidationRegistry.js +0 -143
@@ -1,675 +0,0 @@
1
- /**
2
- * Unified Error Handler Module
3
- * Comprehensive error reporting, handling, and recovery utilities
4
- * Consolidates error handling from multiple sources with enhanced recovery patterns
5
- *
6
- * Sources Consolidated:
7
- * - src/utils/ErrorHandler.js (358 lines, 10 methods)
8
- * - src/worker/integration.js (40 lines, createErrorHandler middleware)
9
- * - bin/database/wrangler-d1-manager.js (50 lines, D1 error analysis)
10
- * - Scattered error response patterns across codebase
11
- * - bin/shared/utils/error-recovery.js (integration for recovery patterns)
12
- *
13
- * @module bin/shared/utils/ErrorHandler
14
- */
15
-
16
- import { ErrorRecoveryManager } from './error-recovery.js';
17
-
18
- /**
19
- * Logger utility - simple console-based logging
20
- * @private
21
- */
22
- const logger = {
23
- info: (message, ...args) => console.log(`[ErrorHandler] ${message}`, ...args),
24
- error: (message, ...args) => console.error(`[ErrorHandler] ${message}`, ...args),
25
- warn: (message, ...args) => console.warn(`[ErrorHandler] ${message}`, ...args),
26
- debug: (message, ...args) => console.debug(`[ErrorHandler] ${message}`, ...args)
27
- };
28
-
29
- /**
30
- * Standardized error response factory
31
- * Creates consistent error response objects across the application
32
- * @param {string} message - Error message
33
- * @param {Object} options - Response options
34
- * @returns {Object} Standardized error response
35
- * @private
36
- */
37
- const _createErrorResponse = (message, options = {}) => {
38
- const {
39
- statusCode = 500,
40
- errorCode = 'INTERNAL_ERROR',
41
- details = {},
42
- includeStack = false,
43
- stack = null
44
- } = options;
45
-
46
- const response = {
47
- error: true,
48
- message,
49
- errorCode,
50
- timestamp: new Date().toISOString(),
51
- ...details
52
- };
53
-
54
- if (includeStack && stack) {
55
- response.stack = stack;
56
- }
57
-
58
- return response;
59
- };
60
-
61
- /**
62
- * Contextual error factory
63
- * Creates errors with attached context for better tracking
64
- * @param {string} message - Error message
65
- * @param {Object} context - Error context
66
- * @returns {Error} Error with context property
67
- * @private
68
- */
69
- const _createContextualError = (message, context = {}) => {
70
- const error = new Error(message);
71
- error.context = context;
72
- error.timestamp = new Date().toISOString();
73
- return error;
74
- };
75
-
76
- /**
77
- * Enhanced Error Handler
78
- * Comprehensive error reporting and handling with recovery integration
79
- */
80
- export class ErrorHandler {
81
- /**
82
- * Initialize ErrorHandler with recovery manager
83
- * @private
84
- */
85
- static initialize() {
86
- if (!ErrorHandler._recoveryManager) {
87
- ErrorHandler._recoveryManager = new ErrorRecoveryManager();
88
- }
89
- }
90
-
91
- /**
92
- * Handle deployment errors with detailed reporting
93
- * @param {Error} error - The error object
94
- * @param {Object} context - Additional context (customer, environment, etc.)
95
- * @returns {Object} Error report with recovery suggestions
96
- */
97
- static handleDeploymentError(error, context = {}) {
98
- this.initialize();
99
-
100
- const { customer, environment, phase, deploymentUrl } = context;
101
-
102
- console.error(`\n❌ Deployment Error in phase: ${phase || 'unknown'}`);
103
- console.error(` Customer: ${customer || 'unknown'}`);
104
- console.error(` Environment: ${environment || 'unknown'}`);
105
- console.error(` Message: ${error.message}`);
106
-
107
- if (error.stack) {
108
- console.error(` Stack: ${error.stack}`);
109
- }
110
-
111
- if (deploymentUrl) {
112
- console.error(` Deployment URL: ${deploymentUrl}`);
113
- }
114
-
115
- // Provide actionable suggestions
116
- const suggestions = this.provideErrorSuggestions(error, context);
117
-
118
- // Attempt recovery if possible
119
- const recovery = this._attemptRecovery(error, context);
120
-
121
- // Create comprehensive report
122
- const report = {
123
- error: error.message,
124
- context: { customer, environment, phase, deploymentUrl },
125
- suggestions,
126
- recovery,
127
- timestamp: new Date().toISOString()
128
- };
129
-
130
- console.error('\n📋 Error Report:', JSON.stringify(report, null, 2));
131
- return report;
132
- }
133
-
134
- /**
135
- * Provide actionable error suggestions
136
- * @param {Error} error - The error object
137
- * @param {Object} context - Context information
138
- * @returns {string[]} Array of suggestion strings
139
- */
140
- static provideErrorSuggestions(error, context = {}) {
141
- console.error('\n💡 Suggestions:');
142
- const suggestions = [];
143
-
144
- const errorMsg = error.message.toLowerCase();
145
-
146
- if (errorMsg.includes('security')) {
147
- suggestions.push('Run security validation: npx clodo-security validate <customer> <environment>');
148
- suggestions.push('Generate secure keys: npx clodo-security generate-key api');
149
- console.error(' - Run security validation: npx clodo-security validate <customer> <environment>');
150
- console.error(' - Generate secure keys: npx clodo-security generate-key api');
151
- }
152
-
153
- if (errorMsg.includes('health check')) {
154
- suggestions.push('Check deployment URL accessibility');
155
- suggestions.push('Verify service is running and responding');
156
- console.error(' - Check deployment URL accessibility');
157
- console.error(' - Verify service is running and responding');
158
- }
159
-
160
- if (errorMsg.includes('authentication')) {
161
- suggestions.push('Re-authenticate with Cloudflare: wrangler auth login');
162
- suggestions.push('Check API token validity');
163
- console.error(' - Re-authenticate with Cloudflare: wrangler auth login');
164
- console.error(' - Check API token validity');
165
- }
166
-
167
- if (errorMsg.includes('timeout')) {
168
- suggestions.push('Increase timeout values in configuration');
169
- suggestions.push('Check network connectivity');
170
- console.error(' - Increase timeout values in configuration');
171
- console.error(' - Check network connectivity');
172
- }
173
-
174
- if (errorMsg.includes('validation')) {
175
- suggestions.push('Review configuration files for errors');
176
- suggestions.push('Run validation checks: npx clodo-config validate');
177
- console.error(' - Review configuration files for errors');
178
- console.error(' - Run validation checks: npx clodo-config validate');
179
- }
180
-
181
- if (suggestions.length === 0) {
182
- suggestions.push('Review logs for more details');
183
- console.error(' - Review logs for more details');
184
- }
185
-
186
- return suggestions;
187
- }
188
-
189
- /**
190
- * Wrap async operations with error handling
191
- * @param {Function} fn - Async function to wrap
192
- * @param {Object} context - Context for error reporting
193
- * @returns {Promise<any>} Result of wrapped function
194
- */
195
- static async withErrorHandling(fn, context = {}) {
196
- try {
197
- return await fn();
198
- } catch (error) {
199
- this.handleDeploymentError(error, context);
200
- throw error;
201
- }
202
- }
203
-
204
- /**
205
- * Handle health check errors specifically
206
- * @param {Error} error - The health check error
207
- * @param {string} url - The URL that was checked
208
- * @returns {Object} Error report with recovery steps
209
- */
210
- static handleHealthCheckError(error, url) {
211
- console.error(`\n❌ Health Check Failed`);
212
- console.error(` URL: ${url}`);
213
- console.error(` Error: ${error.message}`);
214
-
215
- const troubleshooting = [
216
- 'Verify the service is deployed and running',
217
- 'Check if the /health endpoint exists',
218
- 'Ensure the service responds with valid JSON',
219
- 'Check network connectivity and firewall rules',
220
- 'Review service logs for startup errors'
221
- ];
222
-
223
- console.error('\n💡 Health Check Troubleshooting:');
224
- troubleshooting.forEach(step => console.error(` - ${step}`));
225
-
226
- return {
227
- error: 'health_check_failed',
228
- url,
229
- message: error.message,
230
- troubleshooting
231
- };
232
- }
233
-
234
- /**
235
- * Handle D1 database related errors specifically
236
- * @param {Error} error - The D1 database error
237
- * @param {Object} context - Context information (environment, service, etc.)
238
- * @returns {Object} D1 error report with recovery suggestions
239
- */
240
- static handleD1DatabaseError(error, context = {}) {
241
- this.initialize();
242
-
243
- const { environment, service } = context;
244
- console.error(`\n❌ D1 Database Error`);
245
- console.error(` Environment: ${environment || 'unknown'}`);
246
- console.error(` Service: ${service || 'unknown'}`);
247
- console.error(` Error: ${error.message}`);
248
-
249
- const errorMessage = error.message.toLowerCase();
250
- const analysis = this.analyzeD1Error(error);
251
- const troubleshootingSteps = this.getD1TroubleshootingSteps(analysis.category);
252
-
253
- if (errorMessage.includes("couldn't find a d1 db")) {
254
- console.error('\n🗄️ D1 Database Not Found:');
255
- console.error(' - The database specified in wrangler.toml does not exist');
256
- console.error(' - Check database name and ID in [[d1_databases]] section');
257
- console.error(' - List available databases: wrangler d1 list');
258
- console.error(' - Create missing database: wrangler d1 create <database-name>');
259
- console.error(' - Verify you\'re authenticated to the correct Cloudflare account');
260
- } else if (errorMessage.includes('binding') && errorMessage.includes('not found')) {
261
- console.error('\n🔗 D1 Binding Configuration Error:');
262
- console.error(' - Check [[d1_databases]] section in wrangler.toml');
263
- console.error(' - Ensure binding name matches what your code expects');
264
- console.error(' - Verify database_name and database_id are correct');
265
- console.error(' - Example configuration:');
266
- console.error(' [[d1_databases]]');
267
- console.error(' binding = "DB"');
268
- console.error(' database_name = "my-database"');
269
- console.error(' database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"');
270
- } else if (errorMessage.includes('unauthorized') || errorMessage.includes('forbidden')) {
271
- console.error('\n🔒 D1 Permission Error:');
272
- console.error(' - Verify Cloudflare API token has D1 permissions');
273
- console.error(' - Check if you have access to the specified database');
274
- console.error(' - Ensure you\'re authenticated to the correct account');
275
- console.error(' - Re-authenticate: wrangler auth login');
276
- } else if (errorMessage.includes('migration')) {
277
- console.error('\n🔄 D1 Migration Error:');
278
- console.error(' - Check migration files for syntax errors');
279
- console.error(' - Verify migration file names follow correct format');
280
- console.error(' - List migrations: wrangler d1 migrations list <database>');
281
- console.error(' - Apply migrations manually: wrangler d1 migrations apply <database>');
282
- } else {
283
- console.error('\n💡 General D1 Troubleshooting:');
284
- console.error(' - Check Cloudflare account has D1 enabled');
285
- console.error(' - Verify wrangler is up to date: npm install -g wrangler');
286
- console.error(' - List available databases: wrangler d1 list');
287
- console.error(' - Check database status in Cloudflare Dashboard');
288
- console.error(' - Review wrangler.toml configuration file');
289
- }
290
-
291
- console.error('\n📚 Additional Resources:');
292
- console.error(' - D1 Documentation: https://developers.cloudflare.com/d1/');
293
- console.error(' - Wrangler D1 Commands: wrangler d1 --help');
294
- console.error(' - Framework D1 Integration Guide: docs/guides/d1-setup.md');
295
-
296
- return {
297
- error: 'database_error',
298
- environment,
299
- service,
300
- message: error.message,
301
- analysis,
302
- troubleshooting: troubleshootingSteps
303
- };
304
- }
305
-
306
- /**
307
- * Analyze D1 error and provide specific recovery suggestions
308
- * @param {Error} error - The error to analyze
309
- * @returns {Object} Analysis result with suggestions and recovery strategy
310
- */
311
- static analyzeD1Error(error) {
312
- const errorMessage = error.message.toLowerCase();
313
- const analysis = {
314
- isD1Error: false,
315
- category: 'unknown',
316
- severity: 'medium',
317
- autoFixable: false,
318
- suggestions: [],
319
- errorType: null,
320
- databaseName: this._extractDbNameFromError(errorMessage),
321
- bindingName: null,
322
- canRecover: false
323
- };
324
-
325
- // Check if this is a D1 related error
326
- if (errorMessage.includes('d1') || errorMessage.includes('database') || errorMessage.includes('binding')) {
327
- analysis.isD1Error = true;
328
-
329
- // Extract binding name if present
330
- const bindingMatch = error.message.match(/binding '([^']+)'/);
331
- if (bindingMatch) {
332
- analysis.bindingName = bindingMatch[1];
333
- }
334
- }
335
-
336
- if (errorMessage.includes("couldn't find a d1 db")) {
337
- analysis.category = 'database_not_found';
338
- analysis.errorType = 'database_not_found';
339
- analysis.severity = 'high';
340
- analysis.autoFixable = true;
341
- analysis.canRecover = true;
342
- analysis.suggestions = [
343
- 'Run automated D1 recovery: Check available databases and create/configure as needed',
344
- 'Manual fix: wrangler d1 list && wrangler d1 create <name>',
345
- 'Update wrangler.toml with correct database_id'
346
- ];
347
- } else if (errorMessage.includes('binding') && errorMessage.includes('not found')) {
348
- analysis.category = 'binding_configuration';
349
- analysis.errorType = 'binding_configuration_error';
350
- analysis.severity = 'medium';
351
- analysis.autoFixable = true;
352
- analysis.canRecover = true;
353
- analysis.suggestions = [
354
- 'Run configuration validator to check [[d1_databases]] section',
355
- 'Verify binding name matches code expectations',
356
- 'Update database_name and database_id in wrangler.toml'
357
- ];
358
- } else if (errorMessage.includes('unauthorized') || errorMessage.includes('forbidden')) {
359
- analysis.category = 'authentication';
360
- analysis.errorType = 'permission_error';
361
- analysis.severity = 'high';
362
- analysis.autoFixable = false;
363
- analysis.canRecover = false;
364
- analysis.suggestions = [
365
- 'Re-authenticate with Cloudflare: wrangler auth login',
366
- 'Check API token permissions include D1 access',
367
- 'Verify correct Cloudflare account is selected'
368
- ];
369
- } else if (errorMessage.includes('migration')) {
370
- analysis.category = 'migration';
371
- analysis.severity = 'medium';
372
- analysis.autoFixable = false;
373
- analysis.canRecover = false;
374
- analysis.suggestions = [
375
- 'Check migration files for syntax errors',
376
- 'Apply migrations manually: wrangler d1 migrations apply',
377
- 'Reset migrations if needed: wrangler d1 migrations list'
378
- ];
379
- }
380
-
381
- return analysis;
382
- }
383
-
384
- /**
385
- * Get step-by-step D1 troubleshooting guide
386
- * @param {string} errorType - Type of D1 error
387
- * @returns {Array<string>} Step-by-step guide
388
- */
389
- static getD1TroubleshootingSteps(errorType) {
390
- const guides = {
391
- database_not_found: [
392
- '1. List available databases: wrangler d1 list',
393
- '2. Check if database name in wrangler.toml matches an existing database',
394
- '3. If database doesn\'t exist, create it: wrangler d1 create <database-name>',
395
- '4. Copy the database ID from the creation output',
396
- '5. Update database_id in wrangler.toml [[d1_databases]] section',
397
- '6. Retry deployment: npm run deploy'
398
- ],
399
- binding_configuration: [
400
- '1. Open wrangler.toml and locate [[d1_databases]] section',
401
- '2. Verify binding name matches what your code expects (usually "DB")',
402
- '3. Check database_name is correct (no typos)',
403
- '4. Verify database_id is a valid UUID format',
404
- '5. Test configuration: wrangler deploy --dry-run',
405
- '6. If issues persist, validate with: wrangler d1 info <database-name>'
406
- ],
407
- authentication: [
408
- '1. Log out of current session: wrangler logout',
409
- '2. Re-authenticate: wrangler auth login',
410
- '3. Verify correct account: wrangler whoami',
411
- '4. Check API token permissions if using token authentication',
412
- '5. Ensure token has D1:Edit permissions in Cloudflare dashboard',
413
- '6. Retry the operation after successful authentication'
414
- ],
415
- migration: [
416
- '1. Check migration files in migrations/ directory',
417
- '2. Validate SQL syntax in migration files',
418
- '3. List current migration status: wrangler d1 migrations list <database>',
419
- '4. Apply pending migrations: wrangler d1 migrations apply <database>',
420
- '5. If errors occur, check migration file format and naming',
421
- '6. Consider rolling back problematic migrations if needed'
422
- ],
423
- general: [
424
- '1. Check Cloudflare account has D1 enabled and available',
425
- '2. Update wrangler to latest version: npm install -g wrangler',
426
- '3. Verify wrangler.toml file exists and has correct format',
427
- '4. Test authentication: wrangler whoami',
428
- '5. List available D1 databases: wrangler d1 list',
429
- '6. Check Cloudflare Dashboard for any service issues'
430
- ]
431
- };
432
-
433
- return guides[errorType] || guides.general;
434
- }
435
-
436
- /**
437
- * Handle configuration errors
438
- * @param {Error} error - The configuration error
439
- * @param {Object} config - The configuration object that failed
440
- * @returns {Object} Configuration error report
441
- */
442
- static handleConfigurationError(error, config = {}) {
443
- console.error(`\n❌ Configuration Error`);
444
- console.error(` Message: ${error.message}`);
445
-
446
- if (config.customer) {
447
- console.error(` Customer: ${config.customer}`);
448
- }
449
- if (config.environment) {
450
- console.error(` Environment: ${config.environment}`);
451
- }
452
-
453
- console.error('\n💡 Configuration Troubleshooting:');
454
- console.error(' - Validate configuration schema');
455
- console.error(' - Check for missing required fields');
456
- console.error(' - Verify environment variables are set');
457
- console.error(' - Review configuration file syntax');
458
-
459
- return {
460
- error: 'configuration_error',
461
- message: error.message,
462
- context: config,
463
- troubleshooting: [
464
- 'Validate configuration schema',
465
- 'Check for missing required fields',
466
- 'Verify environment variables are set',
467
- 'Review configuration file syntax'
468
- ]
469
- };
470
- }
471
-
472
- /**
473
- * Create a standardized error report
474
- * @param {Error} error - The error object
475
- * @param {Object} context - Additional context
476
- * @returns {Object} Standardized error report
477
- */
478
- static createErrorReport(error, context = {}) {
479
- return {
480
- timestamp: new Date().toISOString(),
481
- error: {
482
- message: error.message,
483
- stack: error.stack,
484
- name: error.name
485
- },
486
- context,
487
- suggestions: this.generateSuggestions(error, context),
488
- recovery: this._attemptRecovery(error, context)
489
- };
490
- }
491
-
492
- /**
493
- * Generate error suggestions based on error type and context
494
- * @param {Error} error - The error object
495
- * @param {Object} context - Context information
496
- * @returns {string[]} Array of suggestion strings
497
- */
498
- static generateSuggestions(error, context = {}) {
499
- const suggestions = [];
500
- const errorMessage = error.message.toLowerCase();
501
-
502
- if (errorMessage.includes('security') || errorMessage.includes('validation')) {
503
- suggestions.push('Run security validation: npx clodo-security validate');
504
- suggestions.push('Generate secure keys: npx clodo-security generate-key api');
505
- }
506
-
507
- if (errorMessage.includes('health') || errorMessage.includes('connection')) {
508
- suggestions.push('Check deployment URL accessibility');
509
- suggestions.push('Verify service is running and responding');
510
- suggestions.push('Check network connectivity and firewall rules');
511
- }
512
-
513
- if (errorMessage.includes('auth') || errorMessage.includes('token')) {
514
- suggestions.push('Re-authenticate with Cloudflare: wrangler auth login');
515
- suggestions.push('Check API token validity and permissions');
516
- }
517
-
518
- if (errorMessage.includes('timeout')) {
519
- suggestions.push('Increase timeout values in configuration');
520
- suggestions.push('Check network connectivity');
521
- }
522
-
523
- if (errorMessage.includes('config') || errorMessage.includes('missing')) {
524
- suggestions.push('Review configuration files for errors');
525
- suggestions.push('Run configuration validation: npx clodo-config validate');
526
- suggestions.push('Check environment variables are properly set');
527
- }
528
-
529
- if (suggestions.length === 0) {
530
- suggestions.push('Review logs for more details');
531
- suggestions.push('Check system resources and dependencies');
532
- }
533
-
534
- return suggestions;
535
- }
536
-
537
- /**
538
- * Creates error handling middleware for Cloudflare Workers
539
- * @param {Object} options - Error handling options
540
- * @returns {Function} Error handling middleware
541
- */
542
- static createErrorHandlingMiddleware(options = {}) {
543
- const {
544
- includeStack = false,
545
- logErrors = true,
546
- transformError = null,
547
- statusCode = 500
548
- } = options;
549
-
550
- return (handler) => {
551
- return async (request, env, ctx) => {
552
- try {
553
- return await handler(request, env, ctx);
554
- } catch (error) {
555
- if (logErrors) {
556
- logger.error(`Request error: ${error.message}`, {
557
- url: request.url,
558
- method: request.method,
559
- stack: includeStack ? error.stack : undefined
560
- });
561
- }
562
-
563
- // Transform error if transformer provided
564
- let errorResponse = _createErrorResponse(error.message, {
565
- statusCode,
566
- includeStack,
567
- stack: error.stack
568
- });
569
-
570
- if (transformError) {
571
- errorResponse = transformError(error, errorResponse);
572
- }
573
-
574
- return new Response(
575
- JSON.stringify(errorResponse),
576
- {
577
- status: statusCode,
578
- headers: { 'Content-Type': 'application/json' }
579
- }
580
- );
581
- }
582
- };
583
- };
584
- }
585
-
586
- /**
587
- * Attempt to recover from error using recovery patterns
588
- * @param {Error} error - The error to recover from
589
- * @param {Object} context - Error context
590
- * @returns {Object} Recovery strategy and status
591
- * @private
592
- */
593
- static _attemptRecovery(error, context = {}) {
594
- this.initialize();
595
-
596
- const errorMsg = error.message.toLowerCase();
597
- const recovery = {
598
- attempted: false,
599
- strategy: null,
600
- canRetry: false,
601
- retryDelay: null,
602
- suggestions: []
603
- };
604
-
605
- // D1 Database errors - can use circuit breaker pattern
606
- if (errorMsg.includes('d1') || errorMsg.includes('database')) {
607
- recovery.strategy = 'circuit_breaker';
608
- recovery.canRetry = true;
609
- recovery.retryDelay = 5000; // 5 seconds
610
- recovery.suggestions = [
611
- 'Will retry with exponential backoff',
612
- 'Circuit breaker will prevent cascading failures',
613
- 'Consider graceful degradation if database is unavailable'
614
- ];
615
- }
616
-
617
- // Timeout errors - can retry with backoff
618
- if (errorMsg.includes('timeout')) {
619
- recovery.strategy = 'exponential_backoff';
620
- recovery.canRetry = true;
621
- recovery.retryDelay = 2000; // 2 seconds initial
622
- recovery.suggestions = [
623
- 'Will retry with exponential backoff and jitter',
624
- 'Maximum 3 retry attempts',
625
- 'Each retry doubles the delay'
626
- ];
627
- }
628
-
629
- // Connection errors - graceful degradation
630
- if (errorMsg.includes('connection') || errorMsg.includes('econnrefused')) {
631
- recovery.strategy = 'graceful_degradation';
632
- recovery.canRetry = true;
633
- recovery.retryDelay = 3000;
634
- recovery.suggestions = [
635
- 'Service will fall back to cached responses if available',
636
- 'Non-critical features will be disabled',
637
- 'Core functionality will remain available'
638
- ];
639
- }
640
-
641
- recovery.attempted = recovery.canRetry;
642
- return recovery;
643
- }
644
-
645
- /**
646
- * Extract database name from error message
647
- * @param {string} errorMessage - The error message
648
- * @returns {string|null} Extracted database name or null
649
- * @private
650
- */
651
- static _extractDbNameFromError(errorMessage) {
652
- const matches = [
653
- /database['"s]?\s*(?:name|id)?['"s]?\s*(?:is|was|:)?\s*['"]*([a-zA-Z0-9_-]+)['"]*/.exec(errorMessage),
654
- /db['"s]?\s*(?::)?\s*['"]*([a-zA-Z0-9_-]+)['"]*/.exec(errorMessage),
655
- /binding\s*['"]*([a-zA-Z0-9_-]+)['"]*/.exec(errorMessage)
656
- ];
657
-
658
- for (const match of matches) {
659
- if (match && match[1]) {
660
- return match[1];
661
- }
662
- }
663
-
664
- return null;
665
- }
666
- }
667
-
668
- // Export factory functions for backward compatibility
669
- export const createErrorResponse = _createErrorResponse;
670
- export const createContextualError = _createContextualError;
671
-
672
- // Export middleware factory
673
- export const createErrorHandler = ErrorHandler.createErrorHandlingMiddleware.bind(ErrorHandler);
674
-
675
- export default ErrorHandler;