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