@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.
- package/CHANGELOG.md +14 -0
- package/dist/bin/clodo-service-old.js +2 -2
- package/dist/bin/commands/create.js +1 -1
- package/dist/bin/commands/diagnose.js +1 -1
- package/dist/bin/commands/update.js +1 -1
- package/dist/bin/commands/validate.js +1 -1
- package/dist/bin/database/enterprise-db-manager.js +3 -3
- package/dist/bin/deployment/enterprise-deploy.js +3 -3
- package/dist/bin/deployment/master-deploy.js +3 -3
- package/dist/bin/deployment/modular-enterprise-deploy.js +3 -3
- package/dist/bin/deployment/modules/DeploymentOrchestrator.js +1 -1
- package/dist/bin/deployment/modules/EnvironmentManager.js +2 -2
- package/dist/bin/portfolio/portfolio-manager.js +3 -3
- package/dist/bin/security/security-cli.js +1 -1
- package/dist/bin/service-management/create-service.js +1 -1
- package/dist/bin/service-management/init-service.js +1 -1
- package/dist/bin/shared/cloudflare/domain-manager.js +1 -1
- package/dist/bin/shared/validation/ValidationRegistry.js +1 -1
- package/dist/deployment/wrangler-deployer.js +1 -1
- package/dist/orchestration/cross-domain-coordinator.js +5 -5
- package/dist/security/index.js +1 -1
- package/dist/service-management/ConfirmationEngine.js +1 -1
- package/dist/service-management/ErrorTracker.js +1 -1
- package/dist/service-management/InputCollector.js +1 -1
- package/dist/service-management/ServiceCreator.js +1 -1
- package/dist/service-management/ServiceInitializer.js +1 -1
- package/dist/utils/config/unified-config-manager.js +1 -1
- package/dist/utils/deployment/config-cache.js +1 -1
- package/dist/utils/deployment/secret-generator.js +1 -1
- package/dist/utils/framework-config.js +1 -1
- package/dist/worker/integration.js +1 -1
- package/package.json +1 -6
- package/bin/README.md +0 -71
- package/bin/clodo-service.js +0 -72
- package/bin/database/README.md +0 -33
- package/bin/database/deployment-db-manager.js +0 -527
- package/bin/database/enterprise-db-manager.js +0 -738
- package/bin/database/wrangler-d1-manager.js +0 -775
- package/bin/security/security-cli.js +0 -117
- package/bin/service-management/README.md +0 -74
- package/bin/service-management/create-service.js +0 -129
- package/bin/service-management/init-service.js +0 -103
- package/bin/service-management/init-service.js.backup +0 -889
- package/bin/shared/cloudflare/domain-discovery.js +0 -637
- package/bin/shared/cloudflare/domain-manager.js +0 -952
- package/bin/shared/cloudflare/index.js +0 -8
- package/bin/shared/cloudflare/ops.js +0 -401
- package/bin/shared/config/ConfigurationManager.js +0 -539
- package/bin/shared/config/cache.js +0 -1230
- package/bin/shared/config/command-config-manager.js +0 -184
- package/bin/shared/config/index.js +0 -21
- package/bin/shared/config/manager.js +0 -315
- package/bin/shared/database/connection-manager.js +0 -374
- package/bin/shared/database/index.js +0 -7
- package/bin/shared/database/orchestrator.js +0 -727
- package/bin/shared/deployment/auditor.js +0 -970
- package/bin/shared/deployment/index.js +0 -10
- package/bin/shared/deployment/rollback-manager.js +0 -570
- package/bin/shared/deployment/validator.js +0 -779
- package/bin/shared/index.js +0 -32
- package/bin/shared/logging/Logger.js +0 -214
- package/bin/shared/monitoring/health-checker.js +0 -484
- package/bin/shared/monitoring/index.js +0 -8
- package/bin/shared/monitoring/memory-manager.js +0 -387
- package/bin/shared/monitoring/production-monitor.js +0 -403
- package/bin/shared/production-tester/api-tester.js +0 -82
- package/bin/shared/production-tester/auth-tester.js +0 -132
- package/bin/shared/production-tester/core.js +0 -197
- package/bin/shared/production-tester/database-tester.js +0 -109
- package/bin/shared/production-tester/index.js +0 -77
- package/bin/shared/production-tester/load-tester.js +0 -131
- package/bin/shared/production-tester/performance-tester.js +0 -103
- package/bin/shared/security/api-token-manager.js +0 -312
- package/bin/shared/security/index.js +0 -8
- package/bin/shared/security/secret-generator.js +0 -942
- package/bin/shared/security/secure-token-manager.js +0 -398
- package/bin/shared/utils/ErrorHandler.js +0 -675
- package/bin/shared/utils/error-recovery.js +0 -245
- package/bin/shared/utils/file-manager.js +0 -162
- package/bin/shared/utils/formatters.js +0 -247
- package/bin/shared/utils/graceful-shutdown-manager.js +0 -390
- package/bin/shared/utils/index.js +0 -19
- package/bin/shared/utils/interactive-prompts.js +0 -146
- package/bin/shared/utils/interactive-utils.js +0 -530
- package/bin/shared/utils/rate-limiter.js +0 -246
- 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;
|