@tamyla/clodo-framework 1.0.0
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 +564 -0
- package/LICENSE +21 -0
- package/README.md +1393 -0
- package/bin/README.md +71 -0
- package/bin/clodo-service.js +416 -0
- package/bin/security/security-cli.js +96 -0
- package/bin/service-management/README.md +74 -0
- package/bin/service-management/create-service.js +129 -0
- package/bin/service-management/init-service.js +102 -0
- package/bin/service-management/init-service.js.backup +889 -0
- package/bin/shared/config/customer-cli.js +293 -0
- package/dist/config/ConfigurationManager.js +159 -0
- package/dist/config/CustomerConfigCLI.js +220 -0
- package/dist/config/FeatureManager.js +426 -0
- package/dist/config/customers.js +441 -0
- package/dist/config/domains.js +180 -0
- package/dist/config/features.js +225 -0
- package/dist/config/index.js +6 -0
- package/dist/database/database-orchestrator.js +730 -0
- package/dist/database/index.js +4 -0
- package/dist/deployment/auditor.js +971 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/rollback-manager.js +523 -0
- package/dist/deployment/testers/api-tester.js +80 -0
- package/dist/deployment/testers/auth-tester.js +129 -0
- package/dist/deployment/testers/core.js +217 -0
- package/dist/deployment/testers/database-tester.js +105 -0
- package/dist/deployment/testers/index.js +74 -0
- package/dist/deployment/testers/load-tester.js +120 -0
- package/dist/deployment/testers/performance-tester.js +105 -0
- package/dist/deployment/validator.js +558 -0
- package/dist/deployment/wrangler-deployer.js +574 -0
- package/dist/handlers/GenericRouteHandler.js +532 -0
- package/dist/index.js +39 -0
- package/dist/migration/MigrationAdapters.js +562 -0
- package/dist/modules/ModuleManager.js +668 -0
- package/dist/modules/security.js +98 -0
- package/dist/orchestration/cross-domain-coordinator.js +1083 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
- package/dist/orchestration/modules/DomainResolver.js +196 -0
- package/dist/orchestration/modules/StateManager.js +332 -0
- package/dist/orchestration/multi-domain-orchestrator.js +255 -0
- package/dist/routing/EnhancedRouter.js +158 -0
- package/dist/schema/SchemaManager.js +778 -0
- package/dist/security/ConfigurationValidator.js +490 -0
- package/dist/security/DeploymentManager.js +208 -0
- package/dist/security/SecretGenerator.js +142 -0
- package/dist/security/SecurityCLI.js +228 -0
- package/dist/security/index.js +51 -0
- package/dist/security/patterns/environment-rules.js +66 -0
- package/dist/security/patterns/insecure-patterns.js +21 -0
- package/dist/service-management/ConfirmationEngine.js +411 -0
- package/dist/service-management/ErrorTracker.js +294 -0
- package/dist/service-management/GenerationEngine.js +3109 -0
- package/dist/service-management/InputCollector.js +237 -0
- package/dist/service-management/ServiceCreator.js +229 -0
- package/dist/service-management/ServiceInitializer.js +448 -0
- package/dist/service-management/ServiceOrchestrator.js +638 -0
- package/dist/service-management/handlers/ConfigMutator.js +130 -0
- package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
- package/dist/service-management/handlers/GenerationHandler.js +80 -0
- package/dist/service-management/handlers/InputHandler.js +59 -0
- package/dist/service-management/handlers/ValidationHandler.js +203 -0
- package/dist/service-management/index.js +7 -0
- package/dist/services/GenericDataService.js +488 -0
- package/dist/shared/cloudflare/domain-discovery.js +562 -0
- package/dist/shared/cloudflare/domain-manager.js +912 -0
- package/dist/shared/cloudflare/index.js +8 -0
- package/dist/shared/cloudflare/ops.js +387 -0
- package/dist/shared/config/cache.js +1167 -0
- package/dist/shared/config/command-config-manager.js +174 -0
- package/dist/shared/config/customer-cli.js +258 -0
- package/dist/shared/config/index.js +9 -0
- package/dist/shared/config/manager.js +289 -0
- package/dist/shared/database/connection-manager.js +338 -0
- package/dist/shared/database/index.js +7 -0
- package/dist/shared/database/orchestrator.js +632 -0
- package/dist/shared/deployment/auditor.js +971 -0
- package/dist/shared/deployment/index.js +10 -0
- package/dist/shared/deployment/rollback-manager.js +523 -0
- package/dist/shared/deployment/validator.js +558 -0
- package/dist/shared/index.js +32 -0
- package/dist/shared/monitoring/health-checker.js +250 -0
- package/dist/shared/monitoring/index.js +8 -0
- package/dist/shared/monitoring/memory-manager.js +382 -0
- package/dist/shared/monitoring/production-monitor.js +390 -0
- package/dist/shared/production-tester/api-tester.js +80 -0
- package/dist/shared/production-tester/auth-tester.js +129 -0
- package/dist/shared/production-tester/core.js +217 -0
- package/dist/shared/production-tester/database-tester.js +105 -0
- package/dist/shared/production-tester/index.js +74 -0
- package/dist/shared/production-tester/load-tester.js +120 -0
- package/dist/shared/production-tester/performance-tester.js +105 -0
- package/dist/shared/security/api-token-manager.js +296 -0
- package/dist/shared/security/index.js +8 -0
- package/dist/shared/security/secret-generator.js +918 -0
- package/dist/shared/security/secure-token-manager.js +379 -0
- package/dist/shared/utils/error-recovery.js +240 -0
- package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
- package/dist/shared/utils/index.js +9 -0
- package/dist/shared/utils/interactive-prompts.js +134 -0
- package/dist/shared/utils/rate-limiter.js +249 -0
- package/dist/utils/ErrorHandler.js +173 -0
- package/dist/utils/deployment/config-cache.js +1160 -0
- package/dist/utils/deployment/index.js +6 -0
- package/dist/utils/deployment/interactive-prompts.js +97 -0
- package/dist/utils/deployment/secret-generator.js +896 -0
- package/dist/utils/dirname-helper.js +35 -0
- package/dist/utils/domain-config.js +159 -0
- package/dist/utils/error-recovery.js +240 -0
- package/dist/utils/esm-helper.js +52 -0
- package/dist/utils/framework-config.js +481 -0
- package/dist/utils/graceful-shutdown-manager.js +379 -0
- package/dist/utils/health-checker.js +114 -0
- package/dist/utils/index.js +36 -0
- package/dist/utils/prompt-handler.js +98 -0
- package/dist/utils/usage-tracker.js +252 -0
- package/dist/utils/validation.js +112 -0
- package/dist/version/VersionDetector.js +723 -0
- package/dist/worker/index.js +4 -0
- package/dist/worker/integration.js +332 -0
- package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
- package/docs/INTEGRATION_GUIDE.md +2045 -0
- package/docs/README.md +82 -0
- package/docs/SECURITY.md +242 -0
- package/docs/deployment/deployment-guide.md +540 -0
- package/docs/overview.md +280 -0
- package/package.json +176 -0
- package/types/index.d.ts +575 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiter for Cloudflare API calls
|
|
3
|
+
* Implements exponential backoff and request queuing to prevent rate limit violations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Rate limiter configuration for different Cloudflare API endpoints
|
|
12
|
+
*/
|
|
13
|
+
const RATE_LIMITS = {
|
|
14
|
+
// Workers API limits (1000/hour, 100/minute)
|
|
15
|
+
workers: {
|
|
16
|
+
maxRequestsPerMinute: 100,
|
|
17
|
+
maxRequestsPerHour: 1000,
|
|
18
|
+
baseDelay: 1000,
|
|
19
|
+
// 1 second
|
|
20
|
+
maxDelay: 300000 // 5 minutes
|
|
21
|
+
},
|
|
22
|
+
// D1 Database API limits (1000/hour)
|
|
23
|
+
d1: {
|
|
24
|
+
maxRequestsPerMinute: 50,
|
|
25
|
+
maxRequestsPerHour: 1000,
|
|
26
|
+
baseDelay: 2000,
|
|
27
|
+
// 2 seconds
|
|
28
|
+
maxDelay: 600000 // 10 minutes
|
|
29
|
+
},
|
|
30
|
+
// General API limits
|
|
31
|
+
general: {
|
|
32
|
+
maxRequestsPerMinute: 30,
|
|
33
|
+
maxRequestsPerHour: 500,
|
|
34
|
+
baseDelay: 3000,
|
|
35
|
+
// 3 seconds
|
|
36
|
+
maxDelay: 900000 // 15 minutes
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Request queue for each API type
|
|
42
|
+
*/
|
|
43
|
+
const requestQueues = {
|
|
44
|
+
workers: [],
|
|
45
|
+
d1: [],
|
|
46
|
+
general: []
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Current request counts and timestamps
|
|
51
|
+
*/
|
|
52
|
+
const requestCounts = {
|
|
53
|
+
workers: {
|
|
54
|
+
minute: 0,
|
|
55
|
+
hour: 0,
|
|
56
|
+
lastMinuteReset: Date.now(),
|
|
57
|
+
lastHourReset: Date.now()
|
|
58
|
+
},
|
|
59
|
+
d1: {
|
|
60
|
+
minute: 0,
|
|
61
|
+
hour: 0,
|
|
62
|
+
lastMinuteReset: Date.now(),
|
|
63
|
+
lastHourReset: Date.now()
|
|
64
|
+
},
|
|
65
|
+
general: {
|
|
66
|
+
minute: 0,
|
|
67
|
+
hour: 0,
|
|
68
|
+
lastMinuteReset: Date.now(),
|
|
69
|
+
lastHourReset: Date.now()
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Reset counters based on time windows
|
|
75
|
+
*/
|
|
76
|
+
function resetCounters() {
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
Object.keys(requestCounts).forEach(apiType => {
|
|
79
|
+
const counts = requestCounts[apiType];
|
|
80
|
+
|
|
81
|
+
// Reset minute counter if needed
|
|
82
|
+
if (now - counts.lastMinuteReset >= 60000) {
|
|
83
|
+
// 1 minute
|
|
84
|
+
counts.minute = 0;
|
|
85
|
+
counts.lastMinuteReset = now;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Reset hour counter if needed
|
|
89
|
+
if (now - counts.lastHourReset >= 3600000) {
|
|
90
|
+
// 1 hour
|
|
91
|
+
counts.hour = 0;
|
|
92
|
+
counts.lastHourReset = now;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Calculate delay based on exponential backoff
|
|
99
|
+
*/
|
|
100
|
+
function calculateDelay(apiType, attempt = 0) {
|
|
101
|
+
const config = RATE_LIMITS[apiType];
|
|
102
|
+
const delay = Math.min(config.baseDelay * Math.pow(2, attempt), config.maxDelay);
|
|
103
|
+
return delay + Math.random() * 1000; // Add jitter
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Check if we can make a request without violating rate limits
|
|
108
|
+
*/
|
|
109
|
+
function canMakeRequest(apiType) {
|
|
110
|
+
resetCounters();
|
|
111
|
+
const counts = requestCounts[apiType];
|
|
112
|
+
const limits = RATE_LIMITS[apiType];
|
|
113
|
+
return counts.minute < limits.maxRequestsPerMinute && counts.hour < limits.maxRequestsPerHour;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Execute a Cloudflare API command with rate limiting
|
|
118
|
+
*/
|
|
119
|
+
async function executeWithRateLimit(command, apiType = 'general', maxRetries = 5) {
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
const attemptRequest = async (attempt = 0) => {
|
|
122
|
+
try {
|
|
123
|
+
// Check if we can make the request
|
|
124
|
+
if (!canMakeRequest(apiType)) {
|
|
125
|
+
const delay = calculateDelay(apiType, attempt);
|
|
126
|
+
console.log(`Rate limit approaching for ${apiType} API. Waiting ${delay}ms before retry...`);
|
|
127
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
128
|
+
return attemptRequest(attempt);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Execute the command
|
|
132
|
+
console.log(`Executing ${apiType} API command (attempt ${attempt + 1}/${maxRetries + 1})`);
|
|
133
|
+
const result = await execAsync(command);
|
|
134
|
+
|
|
135
|
+
// Update counters on success
|
|
136
|
+
requestCounts[apiType].minute++;
|
|
137
|
+
requestCounts[apiType].hour++;
|
|
138
|
+
resolve(result);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
// Check if it's a rate limit error
|
|
141
|
+
if (error.stderr && (error.stderr.includes('rate limit') || error.stderr.includes('429') || error.stderr.includes('Too Many Requests'))) {
|
|
142
|
+
if (attempt < maxRetries) {
|
|
143
|
+
const delay = calculateDelay(apiType, attempt);
|
|
144
|
+
console.log(`Rate limit hit for ${apiType} API. Retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries + 1})`);
|
|
145
|
+
setTimeout(() => attemptRequest(attempt + 1), delay);
|
|
146
|
+
} else {
|
|
147
|
+
reject(new Error(`Rate limit exceeded for ${apiType} API after ${maxRetries + 1} attempts: ${error.message}`));
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
// Not a rate limit error, reject immediately
|
|
151
|
+
reject(error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
attemptRequest();
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Queue a request for execution with rate limiting
|
|
161
|
+
*/
|
|
162
|
+
async function queueRequest(command, apiType = 'general', priority = 'normal') {
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
const request = {
|
|
165
|
+
command,
|
|
166
|
+
apiType,
|
|
167
|
+
priority,
|
|
168
|
+
resolve,
|
|
169
|
+
reject,
|
|
170
|
+
timestamp: Date.now()
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Add to appropriate queue
|
|
174
|
+
requestQueues[apiType].push(request);
|
|
175
|
+
|
|
176
|
+
// Sort by priority (high priority first)
|
|
177
|
+
requestQueues[apiType].sort((a, b) => {
|
|
178
|
+
const priorityOrder = {
|
|
179
|
+
high: 3,
|
|
180
|
+
normal: 2,
|
|
181
|
+
low: 1
|
|
182
|
+
};
|
|
183
|
+
return priorityOrder[b.priority] - priorityOrder[a.priority];
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Process the queue
|
|
187
|
+
processQueue(apiType);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Process the request queue for a specific API type
|
|
193
|
+
*/
|
|
194
|
+
async function processQueue(apiType) {
|
|
195
|
+
const queue = requestQueues[apiType];
|
|
196
|
+
if (queue.length === 0) return;
|
|
197
|
+
|
|
198
|
+
// Only process one request at a time per API type
|
|
199
|
+
if (queue.processing) return;
|
|
200
|
+
queue.processing = true;
|
|
201
|
+
try {
|
|
202
|
+
while (queue.length > 0) {
|
|
203
|
+
const request = queue.shift();
|
|
204
|
+
try {
|
|
205
|
+
const result = await executeWithRateLimit(request.command, request.apiType);
|
|
206
|
+
request.resolve(result);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
request.reject(error);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Small delay between requests to be respectful
|
|
212
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
213
|
+
}
|
|
214
|
+
} finally {
|
|
215
|
+
queue.processing = false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get current rate limit status
|
|
221
|
+
*/
|
|
222
|
+
function getRateLimitStatus(apiType) {
|
|
223
|
+
resetCounters();
|
|
224
|
+
const counts = requestCounts[apiType];
|
|
225
|
+
const limits = RATE_LIMITS[apiType];
|
|
226
|
+
return {
|
|
227
|
+
minute: {
|
|
228
|
+
used: counts.minute,
|
|
229
|
+
limit: limits.maxRequestsPerMinute,
|
|
230
|
+
remaining: Math.max(0, limits.maxRequestsPerMinute - counts.minute)
|
|
231
|
+
},
|
|
232
|
+
hour: {
|
|
233
|
+
used: counts.hour,
|
|
234
|
+
limit: limits.maxRequestsPerHour,
|
|
235
|
+
remaining: Math.max(0, limits.maxRequestsPerHour - counts.hour)
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Clear all queues (useful for testing or emergency situations)
|
|
242
|
+
*/
|
|
243
|
+
function clearQueues() {
|
|
244
|
+
Object.keys(requestQueues).forEach(apiType => {
|
|
245
|
+
requestQueues[apiType].length = 0;
|
|
246
|
+
requestQueues[apiType].processing = false;
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
export { executeWithRateLimit, queueRequest, getRateLimitStatus, clearQueues, RATE_LIMITS };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Error Handler
|
|
3
|
+
* Comprehensive error reporting and handling utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class ErrorHandler {
|
|
7
|
+
/**
|
|
8
|
+
* Handle deployment errors with detailed reporting
|
|
9
|
+
* @param {Error} error - The error object
|
|
10
|
+
* @param {Object} context - Additional context (customer, environment, etc.)
|
|
11
|
+
*/
|
|
12
|
+
static handleDeploymentError(error, context = {}) {
|
|
13
|
+
const {
|
|
14
|
+
customer,
|
|
15
|
+
environment,
|
|
16
|
+
phase
|
|
17
|
+
} = context;
|
|
18
|
+
console.error(`\n❌ Deployment Error in phase: ${phase || 'unknown'}`);
|
|
19
|
+
console.error(` Customer: ${customer || 'unknown'}`);
|
|
20
|
+
console.error(` Environment: ${environment || 'unknown'}`);
|
|
21
|
+
console.error(` Message: ${error.message}`);
|
|
22
|
+
if (error.stack) {
|
|
23
|
+
console.error(` Stack: ${error.stack}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Log additional context if available
|
|
27
|
+
if (context.deploymentUrl) {
|
|
28
|
+
console.error(` Deployment URL: ${context.deploymentUrl}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Provide actionable suggestions
|
|
32
|
+
this.provideErrorSuggestions(error, context);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Provide actionable error suggestions
|
|
37
|
+
* @param {Error} error - The error object
|
|
38
|
+
* @param {Object} context - Context information
|
|
39
|
+
*/
|
|
40
|
+
static provideErrorSuggestions(error, context) {
|
|
41
|
+
console.error('\n💡 Suggestions:');
|
|
42
|
+
if (error.message.includes('security')) {
|
|
43
|
+
console.error(' - Run security validation: npx clodo-security validate <customer> <environment>');
|
|
44
|
+
console.error(' - Generate secure keys: npx clodo-security generate-key api');
|
|
45
|
+
}
|
|
46
|
+
if (error.message.includes('health check')) {
|
|
47
|
+
console.error(' - Check deployment URL accessibility');
|
|
48
|
+
console.error(' - Verify service is running and responding');
|
|
49
|
+
}
|
|
50
|
+
if (error.message.includes('authentication')) {
|
|
51
|
+
console.error(' - Re-authenticate with Cloudflare: wrangler auth login');
|
|
52
|
+
console.error(' - Check API token validity');
|
|
53
|
+
}
|
|
54
|
+
if (error.message.includes('timeout')) {
|
|
55
|
+
console.error(' - Increase timeout values in configuration');
|
|
56
|
+
console.error(' - Check network connectivity');
|
|
57
|
+
}
|
|
58
|
+
if (error.message.includes('validation')) {
|
|
59
|
+
console.error(' - Review configuration files for errors');
|
|
60
|
+
console.error(' - Run validation checks: npx clodo-config validate');
|
|
61
|
+
}
|
|
62
|
+
console.error(' - Review logs for more details');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Wrap async operations with error handling
|
|
67
|
+
* @param {Function} fn - Async function to wrap
|
|
68
|
+
* @param {Object} context - Context for error reporting
|
|
69
|
+
*/
|
|
70
|
+
static async withErrorHandling(fn, context = {}) {
|
|
71
|
+
try {
|
|
72
|
+
return await fn();
|
|
73
|
+
} catch (error) {
|
|
74
|
+
this.handleDeploymentError(error, context);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Handle health check errors specifically
|
|
81
|
+
* @param {Error} error - The health check error
|
|
82
|
+
* @param {string} url - The URL that was checked
|
|
83
|
+
*/
|
|
84
|
+
static handleHealthCheckError(error, url) {
|
|
85
|
+
console.error(`\n❌ Health Check Failed`);
|
|
86
|
+
console.error(` URL: ${url}`);
|
|
87
|
+
console.error(` Error: ${error.message}`);
|
|
88
|
+
console.error('\n💡 Health Check Troubleshooting:');
|
|
89
|
+
console.error(' - Verify the service is deployed and running');
|
|
90
|
+
console.error(' - Check if the /health endpoint exists');
|
|
91
|
+
console.error(' - Ensure the service responds with valid JSON');
|
|
92
|
+
console.error(' - Check network connectivity and firewall rules');
|
|
93
|
+
console.error(' - Review service logs for startup errors');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Handle configuration errors
|
|
98
|
+
* @param {Error} error - The configuration error
|
|
99
|
+
* @param {Object} config - The configuration object that failed
|
|
100
|
+
*/
|
|
101
|
+
static handleConfigurationError(error, config = {}) {
|
|
102
|
+
console.error(`\n❌ Configuration Error`);
|
|
103
|
+
console.error(` Message: ${error.message}`);
|
|
104
|
+
if (config.customer) {
|
|
105
|
+
console.error(` Customer: ${config.customer}`);
|
|
106
|
+
}
|
|
107
|
+
if (config.environment) {
|
|
108
|
+
console.error(` Environment: ${config.environment}`);
|
|
109
|
+
}
|
|
110
|
+
console.error('\n💡 Configuration Troubleshooting:');
|
|
111
|
+
console.error(' - Validate configuration schema');
|
|
112
|
+
console.error(' - Check for missing required fields');
|
|
113
|
+
console.error(' - Verify environment variables are set');
|
|
114
|
+
console.error(' - Review configuration file syntax');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create a standardized error report
|
|
119
|
+
* @param {Error} error - The error object
|
|
120
|
+
* @param {Object} context - Additional context
|
|
121
|
+
* @returns {Object} Standardized error report
|
|
122
|
+
*/
|
|
123
|
+
static createErrorReport(error, context = {}) {
|
|
124
|
+
return {
|
|
125
|
+
timestamp: new Date().toISOString(),
|
|
126
|
+
error: {
|
|
127
|
+
message: error.message,
|
|
128
|
+
stack: error.stack,
|
|
129
|
+
name: error.name
|
|
130
|
+
},
|
|
131
|
+
context,
|
|
132
|
+
suggestions: this.generateSuggestions(error, context)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Generate error suggestions based on error type and context
|
|
138
|
+
* @param {Error} error - The error object
|
|
139
|
+
* @param {Object} context - Context information
|
|
140
|
+
* @returns {string[]} Array of suggestion strings
|
|
141
|
+
*/
|
|
142
|
+
static generateSuggestions(error, context) {
|
|
143
|
+
const suggestions = [];
|
|
144
|
+
const errorMessage = error.message.toLowerCase();
|
|
145
|
+
if (errorMessage.includes('security') || errorMessage.includes('validation')) {
|
|
146
|
+
suggestions.push('Run security validation: npx clodo-security validate');
|
|
147
|
+
suggestions.push('Generate secure keys: npx clodo-security generate-key api');
|
|
148
|
+
}
|
|
149
|
+
if (errorMessage.includes('health') || errorMessage.includes('connection')) {
|
|
150
|
+
suggestions.push('Check deployment URL accessibility');
|
|
151
|
+
suggestions.push('Verify service is running and responding');
|
|
152
|
+
suggestions.push('Check network connectivity and firewall rules');
|
|
153
|
+
}
|
|
154
|
+
if (errorMessage.includes('auth') || errorMessage.includes('token')) {
|
|
155
|
+
suggestions.push('Re-authenticate with Cloudflare: wrangler auth login');
|
|
156
|
+
suggestions.push('Check API token validity and permissions');
|
|
157
|
+
}
|
|
158
|
+
if (errorMessage.includes('timeout')) {
|
|
159
|
+
suggestions.push('Increase timeout values in configuration');
|
|
160
|
+
suggestions.push('Check network connectivity');
|
|
161
|
+
}
|
|
162
|
+
if (errorMessage.includes('config') || errorMessage.includes('missing')) {
|
|
163
|
+
suggestions.push('Review configuration files for errors');
|
|
164
|
+
suggestions.push('Run configuration validation: npx clodo-config validate');
|
|
165
|
+
suggestions.push('Check environment variables are properly set');
|
|
166
|
+
}
|
|
167
|
+
if (suggestions.length === 0) {
|
|
168
|
+
suggestions.push('Review logs for more details');
|
|
169
|
+
suggestions.push('Check system resources and dependencies');
|
|
170
|
+
}
|
|
171
|
+
return suggestions;
|
|
172
|
+
}
|
|
173
|
+
}
|