@bombillazo/error-x 0.1.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,537 @@
1
+ /**
2
+ * Metadata object containing additional context information for an error.
3
+ * Can store any key-value pairs to provide extra debugging or business context.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * const metadata: ErrorMetadata = {
8
+ * userId: 123,
9
+ * operation: 'fetchUser',
10
+ * retryCount: 3
11
+ * }
12
+ * ```
13
+ *
14
+ * @public
15
+ */
16
+ type ErrorMetadata = Record<string, any>;
17
+ /**
18
+ * Predefined display targets for error notifications and UI feedback.
19
+ * These enum values provide consistent, type-safe options for where errors should be displayed.
20
+ *
21
+ * @public
22
+ */
23
+ declare enum HandlingTargets {
24
+ MODAL = "modal",
25
+ TOAST = "toast",
26
+ INLINE = "inline",
27
+ BANNER = "banner",
28
+ CONSOLE = "console",
29
+ LOGGER = "logger",
30
+ NOTIFICATION = "notification"
31
+ }
32
+ /**
33
+ * Display target type that allows both predefined enum values and custom strings.
34
+ * This enables flexibility for custom UI components while providing standard options.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // Using predefined enum values
39
+ * targets: [HandlingTargets.MODAL, HandlingTargets.TOAST]
40
+ *
41
+ * // Using custom strings
42
+ * targets: ['custom-sidebar', 'my-notification-center']
43
+ *
44
+ * // Mixing both
45
+ * targets: [HandlingTargets.MODAL, 'custom-popup', HandlingTargets.CONSOLE]
46
+ * ```
47
+ *
48
+ * @public
49
+ */
50
+ type HandlingTarget = HandlingTargets | string;
51
+ /**
52
+ * Action to display notifications in specified UI targets.
53
+ * Used to notify applications to handle error messages through the indicated display mechanisms.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * {
58
+ * action: 'notify',
59
+ * payload: {
60
+ * targets: [HandlingTargets.TOAST, 'custom-sidebar'],
61
+ * title: 'Error occurred',
62
+ * duration: 5000
63
+ * }
64
+ * }
65
+ * ```
66
+ *
67
+ * @public
68
+ */
69
+ type NotifyAction = {
70
+ action: 'notify';
71
+ payload: {
72
+ targets: HandlingTarget[];
73
+ [key: string]: any;
74
+ };
75
+ };
76
+ /**
77
+ * Action to log out the current user when an error occurs.
78
+ * Useful for authentication errors or session expiration.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * {
83
+ * action: 'logout',
84
+ * payload: {
85
+ * clearStorage: true,
86
+ * redirectURL: '/login'
87
+ * }
88
+ * }
89
+ * ```
90
+ *
91
+ * @public
92
+ */
93
+ type LogoutAction = {
94
+ action: 'logout';
95
+ payload?: {
96
+ [key: string]: any;
97
+ };
98
+ };
99
+ /**
100
+ * Action to redirect the user to a different URL when an error occurs.
101
+ * Commonly used for navigation after authentication errors or access denied scenarios.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * {
106
+ * action: 'redirect',
107
+ * payload: {
108
+ * redirectURL: '/login',
109
+ * delay: 2000,
110
+ * replace: true,
111
+ * }
112
+ * }
113
+ * ```
114
+ *
115
+ * @public
116
+ */
117
+ type RedirectAction = {
118
+ action: 'redirect';
119
+ payload: {
120
+ redirectURL: string;
121
+ [key: string]: any;
122
+ };
123
+ };
124
+ /**
125
+ * Custom action type for application-specific actions.
126
+ * This type is essential for proper TypeScript discrimination in the ErrorAction union.
127
+ * Without this, TypeScript cannot properly distinguish between predefined and custom actions.
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * {
132
+ * action: 'custom',
133
+ * payload: {
134
+ * type: 'analytics',
135
+ * event: 'error_occurred',
136
+ * category: 'authentication',
137
+ * severity: 'high'
138
+ * }
139
+ * }
140
+ *
141
+ * {
142
+ * action: 'custom',
143
+ * payload: {
144
+ * type: 'show-modal',
145
+ * modalId: 'error-modal',
146
+ * title: 'Error',
147
+ * message: 'Something went wrong'
148
+ * }
149
+ * }
150
+ * ```
151
+ *
152
+ * @public
153
+ */
154
+ type CustomAction = {
155
+ action: 'custom';
156
+ payload?: Record<string, any>;
157
+ };
158
+ /**
159
+ * Union type of all possible error actions.
160
+ * Includes predefined actions (NotifyAction, LogoutAction, RedirectAction)
161
+ * and CustomAction for application-specific actions.
162
+ *
163
+ * @public
164
+ */
165
+ type ErrorAction = NotifyAction | LogoutAction | RedirectAction | CustomAction;
166
+ /**
167
+ * Configuration options for creating an ErrorX instance.
168
+ * All properties are optional with sensible defaults.
169
+ *
170
+ * @public
171
+ */
172
+ type ErrorXOptions = {
173
+ /** Technical error message (default: 'An error occurred') */
174
+ message?: string;
175
+ /** Error type/name (default: 'Error') */
176
+ name?: string;
177
+ /** Error identifier code (auto-generated from name if not provided) */
178
+ code?: string | number;
179
+ /** User-friendly message for UI display (default: undefined) */
180
+ uiMessage?: string | undefined;
181
+ /** Original error that caused this error (preserves error chain) */
182
+ cause?: Error | unknown;
183
+ /** Additional context and debugging information (default: undefined) */
184
+ metadata?: ErrorMetadata;
185
+ /** Actions to perform when this error occurs (default: undefined) */
186
+ actions?: ErrorAction[];
187
+ };
188
+ /**
189
+ * JSON-serializable representation of an ErrorX instance.
190
+ * Used for transmitting errors over network or storing in databases.
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const serialized: SerializableError = {
195
+ * name: 'AuthError',
196
+ * message: 'Authentication failed.',
197
+ * code: 'AUTH_FAILED',
198
+ * uiMessage: 'Please check your credentials',
199
+ * stack: 'Error: Authentication failed.\n at login (auth.ts:42:15)',
200
+ * metadata: { userId: 123, loginAttempt: 3 },
201
+ * timestamp: '2024-01-15T10:30:45.123Z',
202
+ * actions: [
203
+ * { action: 'logout', payload: { clearStorage: true } }
204
+ * ],
205
+ * cause: {
206
+ * name: 'NetworkError',
207
+ * message: 'Request timeout.',
208
+ * code: 'NETWORK_TIMEOUT',
209
+ * // ... other error properties
210
+ * }
211
+ * }
212
+ * ```
213
+ *
214
+ * @public
215
+ */
216
+ type SerializableError = {
217
+ /** Error type/name */
218
+ name: string;
219
+ /** Technical error message */
220
+ message: string;
221
+ /** Error identifier code */
222
+ code: string;
223
+ /** User-friendly message for UI display */
224
+ uiMessage: string | undefined;
225
+ /** Stack trace (optional) */
226
+ stack?: string;
227
+ /** Additional context and debugging information */
228
+ metadata: ErrorMetadata | undefined;
229
+ /** ISO timestamp when error was created */
230
+ timestamp: string;
231
+ /** Actions to perform when this error occurs */
232
+ actions?: ErrorAction[];
233
+ /** Serialized cause error (for error chaining) */
234
+ cause?: SerializableError;
235
+ };
236
+
237
+ /**
238
+ * Enhanced Error class with rich metadata, type-safe error handling, and intelligent error conversion.
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * // Basic usage
243
+ * const error = new ErrorX({ message: 'Database connection failed' })
244
+ *
245
+ * // With full options
246
+ * const error = new ErrorX({
247
+ * message: 'User authentication failed',
248
+ * name: 'AuthError',
249
+ * code: 'AUTH_FAILED',
250
+ * uiMessage: 'Please check your credentials',
251
+ * metadata: { userId: 123, loginAttempt: 3 }
252
+ * })
253
+ * ```
254
+ *
255
+ * @public
256
+ */
257
+ declare class ErrorX extends Error {
258
+ /** Error identifier code, auto-generated from name if not provided */
259
+ readonly code: string;
260
+ /** User-friendly message suitable for display in UI */
261
+ readonly uiMessage: string | undefined;
262
+ /** Additional context and metadata associated with the error */
263
+ readonly metadata: ErrorMetadata | undefined;
264
+ /** Timestamp when the error was created */
265
+ readonly timestamp: Date;
266
+ /** Error actions for UI behavior and handling */
267
+ readonly actions: ErrorAction[] | undefined;
268
+ /**
269
+ * Creates a new ErrorX instance with enhanced error handling capabilities.
270
+ *
271
+ * @param options - Configuration options for the error (optional)
272
+ * @param options.message - Technical error message (defaults to 'An error occurred')
273
+ * @param options.name - Error type/name (defaults to 'Error')
274
+ * @param options.code - Error identifier code (auto-generated from name if not provided)
275
+ * @param options.uiMessage - User-friendly message (defaults to undefined)
276
+ * @param options.cause - Original error that caused this error
277
+ * @param options.metadata - Additional context data (defaults to undefined)
278
+ * @param options.actions - Error actions for UI behavior and handling (defaults to undefined)
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * // Create with full options
283
+ * const error = new ErrorX({
284
+ * message: 'Database query failed',
285
+ * name: 'DatabaseError',
286
+ * code: 'DB_QUERY_FAILED',
287
+ * uiMessage: 'Unable to load data. Please try again.',
288
+ * metadata: { query: 'SELECT * FROM users', timeout: 5000 },
289
+ * actions: [
290
+ * {
291
+ * action: 'notify',
292
+ * payload: { targets: [HandlingTargets.TOAST] }
293
+ * },
294
+ * {
295
+ * action: 'redirect',
296
+ * payload: { redirectURL: '/dashboard', delay: 1000 }
297
+ * }
298
+ * ]
299
+ * })
300
+ *
301
+ * // Create with minimal options
302
+ * const simpleError = new ErrorX({ message: 'Something failed' })
303
+ *
304
+ * // Create with no options (uses defaults)
305
+ * const defaultError = new ErrorX()
306
+ * ```
307
+ */
308
+ constructor(options?: ErrorXOptions);
309
+ /**
310
+ * Returns the default error name.
311
+ * @returns Default error name 'Error'
312
+ */
313
+ private static getDefaultName;
314
+ /**
315
+ * Generates a default error code from the error name.
316
+ * Converts camelCase/PascalCase names to UPPER_SNAKE_CASE format.
317
+ *
318
+ * @param name - Error name to convert
319
+ * @returns Generated error code in UPPER_SNAKE_CASE format
320
+ *
321
+ * @example
322
+ * ```typescript
323
+ * generateDefaultCode('DatabaseError') // 'DATABASE_ERROR'
324
+ * generateDefaultCode('userAuthError') // 'USER_AUTH_ERROR'
325
+ * generateDefaultCode('API Timeout') // 'API_TIMEOUT'
326
+ * ```
327
+ */
328
+ private static generateDefaultCode;
329
+ /**
330
+ * Preserves the original error's stack trace while updating the error message.
331
+ * Combines the new error's message with the original error's stack trace.
332
+ *
333
+ * @param originalError - The original error whose stack to preserve
334
+ * @param newError - The new error whose message to use
335
+ * @returns Combined stack trace with new error message and original stack
336
+ */
337
+ private static preserveOriginalStack;
338
+ /**
339
+ * Cleans the stack trace by removing ErrorX internal method calls.
340
+ * This provides cleaner stack traces that focus on user code.
341
+ *
342
+ * @param stack - Raw stack trace to clean
343
+ * @returns Cleaned stack trace without ErrorX internal calls
344
+ */
345
+ private static cleanStack;
346
+ /**
347
+ * Processes an error's stack trace to trim it after a specified delimiter.
348
+ * Useful for removing irrelevant stack frames before a specific function.
349
+ *
350
+ * @param error - Error whose stack to process
351
+ * @param delimiter - String to search for in stack lines
352
+ * @returns Processed stack trace starting after the delimiter
353
+ *
354
+ * @example
355
+ * ```typescript
356
+ * const processed = ErrorX.processErrorStack(error, 'my-app-entry')
357
+ * // Returns stack trace starting after the line containing 'my-app-entry'
358
+ * ```
359
+ */
360
+ private static processErrorStack;
361
+ /**
362
+ * Formats error messages with proper capitalization and punctuation.
363
+ * Ensures consistent message formatting across all ErrorX instances.
364
+ *
365
+ * @param message - Raw error message to format (optional)
366
+ * @returns Formatted message with proper capitalization and punctuation
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * formatMessage('database connection failed') // 'Database connection failed.'
371
+ * formatMessage('user not found. please check credentials') // 'User not found. Please check credentials.'
372
+ * formatMessage() // 'An error occurred'
373
+ * ```
374
+ */
375
+ private static formatMessage;
376
+ /**
377
+ * Creates a new ErrorX instance with additional metadata merged with existing metadata.
378
+ * The original error properties are preserved while extending the metadata.
379
+ *
380
+ * @param additionalMetadata - Additional metadata to merge with existing metadata
381
+ * @returns New ErrorX instance with merged metadata
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const error = new ErrorX({
386
+ * message: 'API request failed',
387
+ * metadata: { endpoint: '/users' }
388
+ * })
389
+ *
390
+ * const enrichedError = error.withMetadata({
391
+ * retryCount: 3,
392
+ * userId: 123
393
+ * })
394
+ * // Result: metadata = { endpoint: '/users', retryCount: 3, userId: 123 }
395
+ * ```
396
+ */
397
+ withMetadata(additionalMetadata: ErrorMetadata): ErrorX;
398
+ /**
399
+ * Type guard that checks if a value is an ErrorX instance.
400
+ *
401
+ * @param value - Value to check
402
+ * @returns True if value is an ErrorX instance, false otherwise
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * try {
407
+ * // some operation
408
+ * } catch (error) {
409
+ * if (ErrorX.isErrorX(error)) {
410
+ * // TypeScript knows error is ErrorX
411
+ * console.log(error.code, error.metadata)
412
+ * }
413
+ * }
414
+ * ```
415
+ */
416
+ static isErrorX(value: unknown): value is ErrorX;
417
+ /**
418
+ * Converts unknown input into an ErrorX instance with intelligent property extraction.
419
+ * Handles strings, regular Error objects, API response objects, and unknown values.
420
+ *
421
+ * @param error - Value to convert to ErrorX
422
+ * @returns ErrorX instance with extracted properties
423
+ *
424
+ * @example
425
+ * ```typescript
426
+ * // Convert string error
427
+ * const error1 = ErrorX.toErrorX('Something went wrong')
428
+ *
429
+ * // Convert regular Error
430
+ * const error2 = ErrorX.toErrorX(new Error('Database failed'))
431
+ *
432
+ * // Convert API response object
433
+ * const apiError = {
434
+ * message: 'User not found',
435
+ * code: 'USER_404',
436
+ * statusText: 'Not Found'
437
+ * }
438
+ * const error3 = ErrorX.toErrorX(apiError)
439
+ * ```
440
+ */
441
+ static toErrorX(error: unknown): ErrorX;
442
+ /**
443
+ * Public wrapper for processing error stack traces with delimiter.
444
+ * Delegates to the private processErrorStack method for implementation.
445
+ *
446
+ * @param error - Error whose stack to process
447
+ * @param delimiter - String to search for in stack lines
448
+ * @returns Processed stack trace starting after the delimiter
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * const error = new Error('Something failed')
453
+ * const cleanStack = ErrorX.processStack(error, 'my-app-entry')
454
+ * // Returns stack trace starting after the line containing 'my-app-entry'
455
+ * ```
456
+ */
457
+ static processStack(error: Error, delimiter: string): string;
458
+ /**
459
+ * Creates a new ErrorX instance with cleaned stack trace using the specified delimiter.
460
+ * Returns the same instance if no delimiter is provided or no stack is available.
461
+ *
462
+ * @param delimiter - Optional string to search for in stack lines
463
+ * @returns New ErrorX instance with cleaned stack trace, or the same instance if no cleaning needed
464
+ *
465
+ * @example
466
+ * ```typescript
467
+ * const error = new ErrorX({ message: 'Database error' })
468
+ * const cleanedError = error.cleanStackTrace('database-layer')
469
+ * // Returns new ErrorX with stack trace starting after 'database-layer'
470
+ * ```
471
+ */
472
+ cleanStackTrace(delimiter?: string): ErrorX;
473
+ /**
474
+ * Converts the ErrorX instance to a detailed string representation.
475
+ * Includes error name, message, code, timestamp, metadata, and stack trace.
476
+ *
477
+ * @returns Formatted string representation of the error
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * const error = new ErrorX({
482
+ * message: 'Database connection failed',
483
+ * name: 'DatabaseError',
484
+ * code: 'DB_CONN_FAILED',
485
+ * metadata: { host: 'localhost', port: 5432 }
486
+ * })
487
+ *
488
+ * console.log(error.toString())
489
+ * // Output: "DatabaseError: Database connection failed. [DB_CONN_FAILED] (2024-01-15T10:30:45.123Z) metadata: {...}"
490
+ * ```
491
+ */
492
+ toString(): string;
493
+ /**
494
+ * Serializes the ErrorX instance to a JSON-compatible object.
495
+ * Recursively serializes the error chain and handles ErrorX or regular Error causes.
496
+ *
497
+ * @returns Serializable object representation of the error
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * const error = new ErrorX({
502
+ * message: 'API request failed',
503
+ * code: 'API_ERROR',
504
+ * metadata: { endpoint: '/users', status: 500 }
505
+ * })
506
+ *
507
+ * const serialized = error.toJSON()
508
+ * // Can be safely passed to JSON.stringify() or sent over network
509
+ * ```
510
+ */
511
+ toJSON(): SerializableError;
512
+ /**
513
+ * Deserializes a JSON object back into an ErrorX instance.
514
+ * Recursively reconstructs the error chain and restores all properties.
515
+ *
516
+ * @param serialized - Serialized error object to deserialize
517
+ * @returns Reconstructed ErrorX instance with restored properties
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * const serializedError = {
522
+ * name: 'DatabaseError',
523
+ * message: 'Connection failed.',
524
+ * code: 'DB_CONN_FAILED',
525
+ * uiMessage: 'Database is temporarily unavailable',
526
+ * metadata: { host: 'localhost' },
527
+ * timestamp: '2024-01-15T10:30:45.123Z'
528
+ * }
529
+ *
530
+ * const error = ErrorX.fromJSON(serializedError)
531
+ * // Fully restored ErrorX instance with all properties
532
+ * ```
533
+ */
534
+ static fromJSON(serialized: SerializableError): ErrorX;
535
+ }
536
+
537
+ export { type CustomAction, type ErrorAction, type ErrorMetadata, ErrorX, type ErrorXOptions, type HandlingTarget, HandlingTargets, type LogoutAction, type NotifyAction, type RedirectAction, type SerializableError };