@paulduvall/claude-dev-toolkit 0.0.1-alpha.1

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.
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Error Factory
3
+ *
4
+ * Standardized error creation factory for consistent error handling across the application.
5
+ * Works in conjunction with ErrorHandlerUtils to provide comprehensive error management.
6
+ *
7
+ * Features:
8
+ * - Standardized error creation methods
9
+ * - Consistent error codes and structures
10
+ * - Context-aware error generation
11
+ * - Integration with error handling workflows
12
+ */
13
+
14
+ const ErrorHandlerUtils = require('./error-handler-utils');
15
+
16
+ class ErrorFactory {
17
+ constructor() {
18
+ this.errorHandler = new ErrorHandlerUtils();
19
+ this.config = {
20
+ errorCodes: this.errorHandler.config.errorCodes,
21
+ defaultContext: {
22
+ timestamp: () => new Date().toISOString(),
23
+ platform: process.platform,
24
+ nodeVersion: process.version
25
+ }
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Create standardized error object
31
+ * @param {string} code - Error code
32
+ * @param {string} message - Error message
33
+ * @param {Object} details - Additional error details
34
+ * @param {Object} context - Error context
35
+ * @returns {Error} Standardized error object
36
+ */
37
+ createStandardError(code, message, details = {}, context = {}) {
38
+ const error = new Error(message);
39
+ error.code = code;
40
+ error.details = details;
41
+ error.context = { ...this.config.defaultContext, ...context };
42
+ error.timestamp = new Date().toISOString();
43
+ return error;
44
+ }
45
+
46
+ /**
47
+ * Create permission-related errors
48
+ */
49
+ createPermissionError(message, path, context = {}) {
50
+ return this.createStandardError(
51
+ this.config.errorCodes.EACCES,
52
+ message,
53
+ { path, type: 'permission' },
54
+ context
55
+ );
56
+ }
57
+
58
+ createNotFoundError(message, path, context = {}) {
59
+ return this.createStandardError(
60
+ this.config.errorCodes.ENOENT,
61
+ message,
62
+ { path, type: 'not_found' },
63
+ context
64
+ );
65
+ }
66
+
67
+ createPermissionDeniedError(operation, path, context = {}) {
68
+ return this.createStandardError(
69
+ this.config.errorCodes.EPERM,
70
+ `Permission denied for ${operation} on ${path}`,
71
+ { operation, path, type: 'permission_denied' },
72
+ context
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Create validation-related errors
78
+ */
79
+ createValidationError(message, field, value, context = {}) {
80
+ return this.createStandardError(
81
+ this.config.errorCodes.VALIDATION_ERROR,
82
+ message,
83
+ { field, value, type: 'validation' },
84
+ context
85
+ );
86
+ }
87
+
88
+ createInvalidInputError(message, input, expectedType = null, context = {}) {
89
+ return this.createStandardError(
90
+ this.config.errorCodes.INVALID_INPUT,
91
+ message,
92
+ { input, expectedType, type: 'invalid_input' },
93
+ context
94
+ );
95
+ }
96
+
97
+ createConfigurationError(message, configPath, configData = null, context = {}) {
98
+ return this.createStandardError(
99
+ this.config.errorCodes.INVALID_CONFIGURATION,
100
+ message,
101
+ { configPath, configData, type: 'configuration' },
102
+ context
103
+ );
104
+ }
105
+
106
+ createMissingRequiredFieldError(field, object, context = {}) {
107
+ return this.createStandardError(
108
+ this.config.errorCodes.MISSING_REQUIRED_FIELD,
109
+ `Missing required field: ${field}`,
110
+ { field, object, type: 'missing_field' },
111
+ context
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Create dependency-related errors
117
+ */
118
+ createDependencyNotFoundError(dependency, details = {}, context = {}) {
119
+ return this.createStandardError(
120
+ this.config.errorCodes.NOT_FOUND,
121
+ `Dependency not found: ${dependency}`,
122
+ { dependency, ...details, type: 'dependency_not_found' },
123
+ context
124
+ );
125
+ }
126
+
127
+ createVersionMismatchError(dependency, current, required, context = {}) {
128
+ return this.createStandardError(
129
+ this.config.errorCodes.VERSION_MISMATCH,
130
+ `Version mismatch for ${dependency}: current ${current}, required ${required}`,
131
+ { dependency, current, required, type: 'version_mismatch' },
132
+ context
133
+ );
134
+ }
135
+
136
+ createDependencyConflictError(dependency1, dependency2, reason, context = {}) {
137
+ return this.createStandardError(
138
+ this.config.errorCodes.DEPENDENCY_CONFLICT,
139
+ `Dependency conflict between ${dependency1} and ${dependency2}: ${reason}`,
140
+ { dependency1, dependency2, reason, type: 'dependency_conflict' },
141
+ context
142
+ );
143
+ }
144
+
145
+ /**
146
+ * Create system-related errors
147
+ */
148
+ createSystemError(message, details = {}, context = {}) {
149
+ return this.createStandardError(
150
+ this.config.errorCodes.SYSTEM_FAILURE,
151
+ message,
152
+ { ...details, type: 'system' },
153
+ context
154
+ );
155
+ }
156
+
157
+ createInsufficientResourcesError(resource, available, required, context = {}) {
158
+ return this.createStandardError(
159
+ this.config.errorCodes.INSUFFICIENT_RESOURCES,
160
+ `Insufficient ${resource}: available ${available}, required ${required}`,
161
+ { resource, available, required, type: 'insufficient_resources' },
162
+ context
163
+ );
164
+ }
165
+
166
+ createCorruptionError(target, details = {}, context = {}) {
167
+ return this.createStandardError(
168
+ this.config.errorCodes.CORRUPTION,
169
+ `Corruption detected in ${target}`,
170
+ { target, ...details, type: 'corruption' },
171
+ context
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Create installation-related errors
177
+ */
178
+ createInstallationError(operation, details = {}, context = {}) {
179
+ return this.createStandardError(
180
+ this.config.errorCodes.INSTALLATION_FAILED,
181
+ `Installation failed during ${operation}`,
182
+ { operation, ...details, type: 'installation' },
183
+ context
184
+ );
185
+ }
186
+
187
+ createBackupError(message, path, details = {}, context = {}) {
188
+ return this.createStandardError(
189
+ this.config.errorCodes.BACKUP_FAILED,
190
+ message,
191
+ { path, ...details, type: 'backup' },
192
+ context
193
+ );
194
+ }
195
+
196
+ createRollbackError(message, operation, details = {}, context = {}) {
197
+ return this.createStandardError(
198
+ this.config.errorCodes.ROLLBACK_FAILED,
199
+ message,
200
+ { operation, ...details, type: 'rollback' },
201
+ context
202
+ );
203
+ }
204
+
205
+ /**
206
+ * Create network-related errors
207
+ */
208
+ createNetworkError(message, url, timeout = null, context = {}) {
209
+ return this.createStandardError(
210
+ this.config.errorCodes.TIMEOUT,
211
+ message,
212
+ { url, timeout, type: 'network' },
213
+ context
214
+ );
215
+ }
216
+
217
+ createConnectionError(message, host, port = null, context = {}) {
218
+ return this.createStandardError(
219
+ this.config.errorCodes.ECONNREFUSED,
220
+ message,
221
+ { host, port, type: 'connection' },
222
+ context
223
+ );
224
+ }
225
+
226
+ createDnsError(message, hostname, context = {}) {
227
+ return this.createStandardError(
228
+ this.config.errorCodes.ENOTFOUND,
229
+ message,
230
+ { hostname, type: 'dns' },
231
+ context
232
+ );
233
+ }
234
+
235
+ /**
236
+ * Create operation-related errors
237
+ */
238
+ createOperationFailedError(operation, reason, details = {}, context = {}) {
239
+ return this.createStandardError(
240
+ this.config.errorCodes.OPERATION_FAILED,
241
+ `Operation failed: ${operation} - ${reason}`,
242
+ { operation, reason, ...details, type: 'operation' },
243
+ context
244
+ );
245
+ }
246
+
247
+ createUnknownError(message = 'An unknown error occurred', details = {}, context = {}) {
248
+ return this.createStandardError(
249
+ this.config.errorCodes.UNKNOWN_ERROR,
250
+ message,
251
+ { ...details, type: 'unknown' },
252
+ context
253
+ );
254
+ }
255
+
256
+ /**
257
+ * Wrap an existing error with enhanced context
258
+ * @param {Error} originalError - Original error to wrap
259
+ * @param {Object} additionalContext - Additional context to add
260
+ * @returns {Error} Enhanced error
261
+ */
262
+ wrapError(originalError, additionalContext = {}) {
263
+ if (!originalError) {
264
+ return this.createUnknownError('No error provided', {}, additionalContext);
265
+ }
266
+
267
+ const enhanced = this.errorHandler.createEnhancedError(originalError, additionalContext);
268
+
269
+ // Create new error with enhanced information
270
+ const wrappedError = new Error(enhanced.message);
271
+ wrappedError.code = enhanced.code;
272
+ wrappedError.details = enhanced.details || {};
273
+ wrappedError.context = enhanced.context;
274
+ wrappedError.category = enhanced.category;
275
+ wrappedError.severity = enhanced.severity;
276
+ wrappedError.recoverable = enhanced.recoverable;
277
+ wrappedError.originalError = originalError;
278
+ wrappedError.timestamp = enhanced.timestamp;
279
+
280
+ return wrappedError;
281
+ }
282
+
283
+ /**
284
+ * Create error from string with automatic categorization
285
+ * @param {string} errorString - Error string
286
+ * @param {Object} context - Error context
287
+ * @returns {Error} Categorized error
288
+ */
289
+ createFromString(errorString, context = {}) {
290
+ if (!errorString || typeof errorString !== 'string') {
291
+ return this.createInvalidInputError('Invalid error string provided', errorString, 'string', context);
292
+ }
293
+
294
+ // Try to detect error type from string content
295
+ const lowerString = errorString.toLowerCase();
296
+
297
+ if (lowerString.includes('permission') || lowerString.includes('access')) {
298
+ return this.createPermissionError(errorString, null, context);
299
+ }
300
+
301
+ if (lowerString.includes('not found') || lowerString.includes('missing')) {
302
+ return this.createNotFoundError(errorString, null, context);
303
+ }
304
+
305
+ if (lowerString.includes('network') || lowerString.includes('timeout')) {
306
+ return this.createNetworkError(errorString, null, null, context);
307
+ }
308
+
309
+ if (lowerString.includes('validation') || lowerString.includes('invalid')) {
310
+ return this.createValidationError(errorString, null, null, context);
311
+ }
312
+
313
+ // Default to generic error
314
+ return this.createStandardError(
315
+ this.config.errorCodes.STRING_ERROR,
316
+ errorString,
317
+ { originalString: errorString, type: 'string_error' },
318
+ context
319
+ );
320
+ }
321
+
322
+ /**
323
+ * Create error with automatic retry configuration
324
+ * @param {string} code - Error code
325
+ * @param {string} message - Error message
326
+ * @param {Object} details - Error details
327
+ * @param {Object} retryConfig - Retry configuration
328
+ * @param {Object} context - Error context
329
+ * @returns {Error} Error with retry configuration
330
+ */
331
+ createRetryableError(code, message, details = {}, retryConfig = {}, context = {}) {
332
+ const error = this.createStandardError(code, message, details, context);
333
+
334
+ error.retryConfig = {
335
+ maxAttempts: 3,
336
+ delay: 1000,
337
+ backoff: 'exponential',
338
+ retryable: true,
339
+ ...retryConfig
340
+ };
341
+
342
+ return error;
343
+ }
344
+
345
+ /**
346
+ * Create contextual error for specific operations
347
+ * @param {string} operation - Operation being performed
348
+ * @param {Error|string} originalError - Original error or error message
349
+ * @param {Object} operationContext - Operation-specific context
350
+ * @returns {Error} Contextual error
351
+ */
352
+ createContextualError(operation, originalError, operationContext = {}) {
353
+ const context = {
354
+ operation,
355
+ ...operationContext,
356
+ timestamp: new Date().toISOString()
357
+ };
358
+
359
+ if (originalError instanceof Error) {
360
+ return this.wrapError(originalError, context);
361
+ } else if (typeof originalError === 'string') {
362
+ return this.createFromString(originalError, context);
363
+ } else {
364
+ return this.createOperationFailedError(operation, 'Unknown error occurred', { originalError }, context);
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Batch create multiple errors with consistent context
370
+ * @param {Array} errorSpecs - Array of error specifications
371
+ * @param {Object} sharedContext - Shared context for all errors
372
+ * @returns {Array<Error>} Array of created errors
373
+ */
374
+ createBatch(errorSpecs, sharedContext = {}) {
375
+ return errorSpecs.map(spec => {
376
+ const { code, message, details = {}, context = {} } = spec;
377
+ const combinedContext = { ...sharedContext, ...context };
378
+ return this.createStandardError(code, message, details, combinedContext);
379
+ });
380
+ }
381
+
382
+ /**
383
+ * Get error factory instance (singleton pattern)
384
+ * @returns {ErrorFactory} Error factory instance
385
+ */
386
+ static getInstance() {
387
+ if (!ErrorFactory._instance) {
388
+ ErrorFactory._instance = new ErrorFactory();
389
+ }
390
+ return ErrorFactory._instance;
391
+ }
392
+ }
393
+
394
+ module.exports = ErrorFactory;