error-message-utils 1.2.13 → 1.2.14

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/README.md CHANGED
@@ -6,6 +6,7 @@ consistent shape:
6
6
  - a readable message
7
7
  - a stable error code
8
8
  - optional extra data
9
+ - an optional native error cause
9
10
 
10
11
  Use `Exception` for most application code. Use `encodeError` and `decodeError` when you need to
11
12
  send or receive an error code inside a plain string.
@@ -18,7 +19,8 @@ npm i -S error-message-utils
18
19
 
19
20
  ## Recommended Usage: Exception
20
21
 
21
- `Exception` is an `Error` subclass that stores a normalized message, a code, and optional data.
22
+ `Exception` is an `Error` subclass that stores a normalized message, a code, optional data, and an
23
+ optional native cause.
22
24
 
23
25
  ```typescript
24
26
  import { Exception } from 'error-message-utils';
@@ -37,6 +39,7 @@ exception.name; // 'Exception'
37
39
  exception.message; // 'Request failed'
38
40
  exception.code; // 'REQUEST_FAILED'
39
41
  exception.data; // null
42
+ exception.cause; // undefined
40
43
  exception.toString(); // 'Request failed{(REQUEST_FAILED)}'
41
44
  exception.toRecord();
42
45
  // {
@@ -46,29 +49,51 @@ exception.toRecord();
46
49
  // }
47
50
  ```
48
51
 
49
- ### Wrap Unknown Errors
52
+ ### Preserve an Error Cause
50
53
 
51
- When you catch an unknown error, pass it to `Exception`. The package will extract the best message
52
- and code it can find.
54
+ When wrapping an error, provide a stable contextual message and pass the original value through the
55
+ fourth `IErrorOptions` argument. This keeps the top-level message predictable while preserving the
56
+ original error for debugging.
53
57
 
54
58
  ```typescript
55
- import { Exception } from 'error-message-utils';
59
+ import { Exception, extractMessage } from 'error-message-utils';
56
60
 
57
61
  try {
58
62
  await sendReceiptEmail();
59
- } catch (error) {
60
- throw new Exception(error, 'RECEIPT_EMAIL_FAILED', {
61
- operation: 'sendReceiptEmail',
62
- });
63
+ } catch (cause) {
64
+ const exception = new Exception(
65
+ 'Unable to send the receipt email.',
66
+ 'RECEIPT_EMAIL_FAILED',
67
+ { operation: 'sendReceiptEmail' },
68
+ { cause },
69
+ );
70
+
71
+ exception.message; // 'Unable to send the receipt email.'
72
+ exception.cause === cause; // true
73
+ extractMessage(exception); // combines the message with a truthy cause chain
74
+
75
+ throw exception;
63
76
  }
64
77
  ```
65
78
 
79
+ `IErrorOptions` is a direct alias of the native `ErrorOptions` type. This API requires the ES2022
80
+ TypeScript `lib` and a runtime that supports `Error` causes.
81
+
82
+ The existing `new Exception(error, code, data)` form remains supported. It normalizes the first
83
+ argument into the exception message but does not infer or store that argument as `cause`. Avoid
84
+ also appending the cause message to the top-level message because `extractMessage` already combines
85
+ truthy cause chains. Native `Error` semantics still retain falsy causes such as `false`, `0`, an
86
+ empty string, or `null`, but `extractMessage` does not append them.
87
+
88
+ `toString()` and `toRecord()` intentionally omit `cause`. A cause can contain internal or sensitive
89
+ details, so inspect or expose it only at an appropriate boundary.
90
+
66
91
  ### Extend Exception
67
92
 
68
93
  Create small domain-specific exception classes when your app has a stable set of error codes.
69
94
 
70
95
  ```typescript
71
- import { Exception } from 'error-message-utils';
96
+ import { Exception, type IErrorOptions } from 'error-message-utils';
72
97
 
73
98
  const USER_ERROR_CODES = {
74
99
  EmailTaken: 'USER_EMAIL_TAKEN',
@@ -78,8 +103,13 @@ const USER_ERROR_CODES = {
78
103
  type IUserErrorCode = (typeof USER_ERROR_CODES)[keyof typeof USER_ERROR_CODES];
79
104
 
80
105
  export class UserException extends Exception {
81
- public constructor(message: string, code: IUserErrorCode, data?: unknown) {
82
- super(message, code, data);
106
+ public constructor(
107
+ message: string,
108
+ code: IUserErrorCode,
109
+ data?: unknown,
110
+ options?: IErrorOptions,
111
+ ) {
112
+ super(message, code, data, options);
83
113
  this.name = 'UserException';
84
114
  }
85
115
  }
@@ -264,6 +294,7 @@ import {
264
294
  type IDecodedError,
265
295
  type IErrorCode,
266
296
  type IErrorCodeCarrier,
297
+ type IErrorOptions,
267
298
  type IExceptionRecord,
268
299
  } from 'error-message-utils';
269
300
  ```
@@ -272,7 +303,7 @@ import {
272
303
 
273
304
  | Export | Description |
274
305
  | --- | --- |
275
- | `Exception` | An `Error` subclass that normalizes an unknown error into `message`, `code`, and `data`. It can also serialize itself with `toString()` or `toRecord()`. |
306
+ | `Exception` | An `Error` subclass that normalizes an unknown error into `message`, `code`, and `data`, and accepts native error options such as `cause`. It can also serialize itself with `toString()` or `toRecord()`, which omit the cause. |
276
307
 
277
308
  ### Functions
278
309
 
@@ -293,6 +324,8 @@ import {
293
324
  ```typescript
294
325
  type IErrorCode = string | number;
295
326
 
327
+ type IErrorOptions = ErrorOptions;
328
+
296
329
  type IDecodedError = {
297
330
  message: string;
298
331
  code: IErrorCode;
@@ -313,9 +346,10 @@ type IExceptionRecord = {
313
346
  | Export | Description |
314
347
  | --- | --- |
315
348
  | `IErrorCode` | The supported type for application error codes. |
349
+ | `IErrorOptions` | A direct alias of the native `ErrorOptions` type accepted by the `Exception` constructor. |
316
350
  | `IDecodedError` | The object returned by `decodeError`. |
317
351
  | `IErrorCodeCarrier` | A plain object shape that can provide a code to `decodeError`, `getErrorCode`, `hasErrorCode`, `hasErrorCodePrefix`, and `Exception`. |
318
- | `IExceptionRecord` | The serializable object returned by `Exception.toRecord()`. |
352
+ | `IExceptionRecord` | The serializable object returned by `Exception.toRecord()`. It does not include `cause`. |
319
353
 
320
354
  ### Constants
321
355
 
@@ -1,7 +1,7 @@
1
- import { type IErrorCode } from '../shared/types.js';
2
- import { type IExceptionRecord } from './types.js';
1
+ import type { IErrorCode } from '../shared/types.js';
2
+ import type { IErrorOptions, IExceptionRecord } from './types.js';
3
3
  /**
4
- * Error subclass that normalizes unknown errors into a message, code, and optional data payload.
4
+ * Error subclass that normalizes unknown errors and supports native error options.
5
5
  */
6
6
  export declare class Exception extends Error {
7
7
  readonly code: IErrorCode;
@@ -11,8 +11,9 @@ export declare class Exception extends Error {
11
11
  * @param error The unknown error or message to normalize.
12
12
  * @param code The optional code that overrides any decoded code.
13
13
  * @param data The optional data payload that overrides any decoded data.
14
+ * @param options The native error options, including an optional cause.
14
15
  */
15
- constructor(error: unknown, code?: IErrorCode, data?: unknown);
16
+ constructor(error: unknown, code?: IErrorCode, data?: unknown, options?: IErrorOptions);
16
17
  /**
17
18
  * Override the default toString method to return a formatted error message with the code.
18
19
  * @returns A string representation of the error with the code.
@@ -1 +1 @@
1
- import{decodeError,encodeError}from"../error-handler/index.js";export class Exception extends Error{code;data;constructor(e,r,t){const o=decodeError(e);super(o.message),this.name="Exception",this.code=r??o.code,this.data=void 0===t?o.data:t}toString(){return encodeError(this.message,this.code)}[Symbol.toPrimitive](e){return"string"===e||"default"===e?this.toString():null}toRecord(){return{message:this.message,code:this.code,data:this.data??null}}}
1
+ import{decodeError,encodeError}from"../error-handler/index.js";export class Exception extends Error{code;data;constructor(e,r,t,o){const s=decodeError(e);super(s.message,o),this.name="Exception",this.code=r??s.code,this.data=void 0===t?s.data:t}toString(){return encodeError(this.message,this.code)}[Symbol.toPrimitive](e){return"string"===e||"default"===e?this.toString():null}toRecord(){return{message:this.message,code:this.code,data:this.data??null}}}
@@ -1,2 +1,2 @@
1
- export type { IExceptionRecord } from './types.js';
1
+ export type { IErrorOptions, IExceptionRecord } from './types.js';
2
2
  export { Exception } from './exception.js';
@@ -1,4 +1,5 @@
1
- import { IErrorCode } from '../shared/types.js';
1
+ import type { IErrorCode } from '../shared/types.js';
2
+ export type IErrorOptions = ErrorOptions;
2
3
  export type IExceptionRecord = {
3
4
  message: string;
4
5
  code: IErrorCode;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export type { IErrorCode, IDecodedError, IErrorCodeCarrier } from './shared/types.js';
2
2
  export { DEFAULT_CODE, DEFAULT_MESSAGE } from './shared/constants.js';
3
3
  export { extractMessage, extractRedactedMessage, encodeError, decodeError, isEncodedError, getErrorCode, hasErrorCodePrefix, hasErrorCode, isDefaultErrorMessage, } from './error-handler/index.js';
4
- export { type IExceptionRecord, Exception } from './exception/index.js';
4
+ export { type IErrorOptions, type IExceptionRecord, Exception } from './exception/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "error-message-utils",
3
- "version": "1.2.13",
3
+ "version": "1.2.14",
4
4
  "description": "The error-message-utils package simplifies error management in your web applications and RESTful APIs. It ensures consistent and scalable handling of error messages, saving you time and effort. Moreover, it gives you the ability to assign custom error codes so all possible cases can be handled accordingly.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",