error-message-utils 1.2.9 → 1.2.11

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
@@ -1,249 +1,302 @@
1
1
  # Error Message Utils
2
2
 
3
- 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.
3
+ `error-message-utils` helps TypeScript and JavaScript apps turn unknown errors into a
4
+ consistent shape:
4
5
 
6
+ - a readable message
7
+ - a stable error code
8
+ - optional extra data
5
9
 
10
+ Use `Exception` for most application code. Use `encodeError` and `decodeError` when you need to
11
+ send or receive an error code inside a plain string.
6
12
 
13
+ ## Install
7
14
 
15
+ ```bash
16
+ npm i -S error-message-utils
17
+ ```
8
18
 
9
- </br>
19
+ ## Recommended Usage: Exception
10
20
 
11
- ## Getting Started
21
+ `Exception` is an `Error` subclass that stores a normalized message, a code, and optional data.
12
22
 
13
- Install the package:
14
- ```bash
15
- npm i -S error-message-utils
23
+ ```typescript
24
+ import { Exception } from 'error-message-utils';
25
+
26
+ throw new Exception('The provided email is already in use.', 'EMAIL_EXISTS', {
27
+ field: 'email',
28
+ });
29
+ ```
30
+
31
+ ```typescript
32
+ const exception = new Exception('Request failed', 'REQUEST_FAILED');
33
+
34
+ exception instanceof Error; // true
35
+ exception instanceof Exception; // true
36
+ exception.name; // 'Exception'
37
+ exception.message; // 'Request failed'
38
+ exception.code; // 'REQUEST_FAILED'
39
+ exception.data; // null
40
+ exception.toString(); // 'Request failed{(REQUEST_FAILED)}'
41
+ exception.toRecord();
42
+ // {
43
+ // message: 'Request failed',
44
+ // code: 'REQUEST_FAILED',
45
+ // data: null,
46
+ // }
16
47
  ```
17
48
 
18
- ### Examples
49
+ ### Wrap Unknown Errors
19
50
 
20
- Encode an error:
51
+ When you catch an unknown error, pass it to `Exception`. The package will extract the best message
52
+ and code it can find.
21
53
 
22
54
  ```typescript
23
- import { encodeError } from 'error-message-utils';
24
-
25
- if (emailExists()) {
26
- throw new Error(encodeError(
27
- 'The provided email is already in use.',
28
- 'EMAIL_EXISTS'
29
- ));
30
- // 'The provided email is already in use.{(EMAIL_EXISTS)}'
55
+ import { Exception } from 'error-message-utils';
56
+
57
+ try {
58
+ await sendReceiptEmail();
59
+ } catch (error) {
60
+ throw new Exception(error, 'RECEIPT_EMAIL_FAILED', {
61
+ operation: 'sendReceiptEmail',
62
+ });
31
63
  }
32
64
  ```
33
65
 
66
+ ### Extend Exception
34
67
 
35
- <br/>
36
-
37
- Decode an error:
68
+ Create small domain-specific exception classes when your app has a stable set of error codes.
38
69
 
39
70
  ```typescript
40
- import { decodeError } from 'error-message-utils';
71
+ import { Exception } from 'error-message-utils';
41
72
 
42
- decodeError('The provided email is already in use.{(EMAIL_EXISTS)}');
43
- // {
44
- // message: 'The provided email is already in use.',
45
- // code: 'EMAIL_EXISTS'
46
- // }
73
+ const USER_ERROR_CODES = {
74
+ EmailTaken: 'USER_EMAIL_TAKEN',
75
+ Unauthorized: 'USER_UNAUTHORIZED',
76
+ } as const;
77
+
78
+ type IUserErrorCode = (typeof USER_ERROR_CODES)[keyof typeof USER_ERROR_CODES];
79
+
80
+ export class UserException extends Exception {
81
+ public constructor(message: string, code: IUserErrorCode, data?: unknown) {
82
+ super(message, code, data);
83
+ this.name = 'UserException';
84
+ }
85
+ }
86
+
87
+ throw new UserException(
88
+ 'The provided email is already in use.',
89
+ USER_ERROR_CODES.EmailTaken,
90
+ { field: 'email' },
91
+ );
47
92
  ```
48
93
 
94
+ ## Common Tasks
49
95
 
50
- <br/>
96
+ ### Extract a Message
51
97
 
52
- Error messages can be extracted recursively from complex structures, including nested `cause` data properties from `Error` instances:
98
+ `extractMessage` accepts any value and returns the best readable message it can find.
53
99
 
54
100
  ```typescript
55
101
  import { extractMessage } from 'error-message-utils';
56
102
 
57
- extractMessage(new Error('Top level error', {
58
- cause: new Error('First nested cause', {
59
- cause: new Error('Second nested cause'),
103
+ extractMessage(
104
+ new Error('Top level error', {
105
+ cause: new Error('First nested cause', {
106
+ cause: new Error('Second nested cause'),
107
+ }),
60
108
  }),
61
- }));
109
+ );
62
110
  // 'Top level error; [CAUSE]: First nested cause; [CAUSE]: Second nested cause'
63
111
 
64
-
65
- extractMessage({
66
- message: {
67
- err: {
68
- message: 'This error message is nested deeply!'
69
- }
70
- }
112
+ extractMessage({
113
+ message: {
114
+ err: {
115
+ message: 'This error message is nested deeply!',
116
+ },
117
+ },
71
118
  });
72
119
  // 'This error message is nested deeply!'
73
120
  ```
74
121
 
75
-
76
- <br/>
77
-
78
- Extract detailed error messages from [Zod](https://zod.dev/basics) parsing errors.
122
+ Zod errors are formatted with their first issue message and path.
79
123
 
80
124
  ```typescript
81
- import { z } from "zod";
125
+ import { z } from 'zod';
82
126
  import { extractMessage } from 'error-message-utils';
83
127
 
84
- z.object({ name: z.string() }).parse({ name: 123 });
85
- // Invalid input: expected string, received number (name)
128
+ const result = z.object({ name: z.string() }).safeParse({ name: 123 });
86
129
 
87
- z.object({
88
- name: z.object({ age: z.number() })
89
- }).parse({ name: { age: 'not a number' } })
90
- // Invalid input: expected string, received number (someDict.innerList.0.someProp)
130
+ if (!result.success) {
131
+ extractMessage(result.error);
132
+ // 'Invalid input: expected string, received number (name)'
133
+ }
91
134
  ```
92
135
 
136
+ ### Get an Error Code
93
137
 
94
- <br/>
95
-
96
- Identify encoded errors:
138
+ Use `getErrorCode` when you only need the resolved code.
97
139
 
98
140
  ```typescript
99
- import { isEncodedError, encodeError, isErrorCodeCarrier, hasErrorCode } from 'error-message-utils';
100
-
101
- isEncodedError('Some random unencoded error');
102
- // false
141
+ import { Exception, getErrorCode } from 'error-message-utils';
103
142
 
104
- isEncodedError(new Error('Some random unencoded error'));
105
- // false
143
+ const exception = new Exception('Access denied', 'ACCESS_DENIED');
106
144
 
107
- isEncodedError(encodeError('Some unknown error.', 'NASTY_ERROR'));
108
- // true
145
+ getErrorCode(exception); // 'ACCESS_DENIED'
146
+ getErrorCode('Access denied'); // null
147
+ ```
109
148
 
110
- isEncodedError(encodeError(new Error('Some unknown error.'), 'NASTY_ERROR'));
111
- // true
149
+ Use `hasErrorCode` when you want a direct boolean check.
112
150
 
113
- const error = new Error('Oops, something went wrong.');
114
- const exception = new Exception('Oops, something went wrong.', 'MY_ERROR_CODE');
151
+ ```typescript
152
+ import { Exception, hasErrorCode } from 'error-message-utils';
115
153
 
116
- isErrorCodeCarrier(error); // false
117
- hasErrorCode(error, 'MY_ERROR_CODE'); // false
154
+ const exception = new Exception('Access denied', 'ACCESS_DENIED');
118
155
 
119
- isErrorCodeCarrier(exception); // true
120
- hasErrorCode(exception, 'MY_ERROR_CODE'); // true
156
+ hasErrorCode(exception, 'ACCESS_DENIED'); // true
157
+ hasErrorCode(exception, 'PAYMENT_FAILED'); // false
121
158
  ```
122
159
 
160
+ ### Encode and Decode Plain Strings
123
161
 
124
- <br/>
125
-
126
- In some cases, you may want to check whether the extracted error matches the default message provided by this package:
162
+ `encodeError` and `decodeError` are lower-level helpers for systems that can only pass string
163
+ messages.
127
164
 
128
165
  ```typescript
129
- import { isDefaultErrorMessage } from 'error-message-utils';
166
+ import { decodeError, encodeError } from 'error-message-utils';
130
167
 
131
- const DEFAULT_MESSAGE: string = 'The error message could not be extracted, check the logs for more information.';
168
+ const encodedError = encodeError(
169
+ 'The provided email is already in use.',
170
+ 'EMAIL_EXISTS',
171
+ );
132
172
 
133
- isDefaultErrorMessage(DEFAULT_MESSAGE);
134
- // true
173
+ encodedError;
174
+ // 'The provided email is already in use.{(EMAIL_EXISTS)}'
135
175
 
136
- isDefaultErrorMessage(`${DEFAULT_MESSAGE} and something else...`);
137
- // false
138
-
139
- isDefaultErrorMessage(`${DEFAULT_MESSAGE} and something else...`, true);
140
- // true
176
+ decodeError(encodedError);
177
+ // {
178
+ // message: 'The provided email is already in use.',
179
+ // code: 'EMAIL_EXISTS',
180
+ // data: null,
181
+ // }
141
182
  ```
142
183
 
184
+ ### Detect Resolved Codes with isEncodedError
143
185
 
186
+ `isEncodedError` returns `true` when an error resolves to a non-default code. For direct code
187
+ inspection, prefer `getErrorCode` or `hasErrorCode`.
144
188
 
189
+ ```typescript
190
+ import { encodeError, isEncodedError } from 'error-message-utils';
191
+
192
+ isEncodedError('Some random unencoded error'); // false
193
+ isEncodedError(new Error('Some random unencoded error')); // false
194
+ isEncodedError(encodeError('Some unknown error.', 'UNKNOWN_ERROR')); // true
195
+ ```
145
196
 
146
- <br/>
197
+ ### Check the Default Message
147
198
 
148
- Improve code consistency by handling errors with the `Exception` utility class:
199
+ Use `isDefaultErrorMessage` to detect the fallback message returned when no useful message can be
200
+ extracted.
149
201
 
150
202
  ```typescript
151
- import { Exception } from 'error-message-utils';
203
+ import { DEFAULT_MESSAGE, isDefaultErrorMessage } from 'error-message-utils';
152
204
 
153
- const exception = new Exception('Request failed', 'SOME_ERROR_CODE');
154
- exception instanceof Error; // true
155
- exception instanceof Exception; // true
156
- exception.message; // "Request failed"
157
- exception.code; // "SOME_ERROR_CODE"
158
- exception.toString(); // "Request failed{(SOME_ERROR_CODE)}"
159
- exception.toRecord();
160
- // {
161
- // message: "Request failed",
162
- // code: "SOME_ERROR_CODE",
163
- // data: null,
164
- // }
205
+ isDefaultErrorMessage(DEFAULT_MESSAGE); // true
206
+ isDefaultErrorMessage(`${DEFAULT_MESSAGE} More details.`); // true
207
+ isDefaultErrorMessage(`${DEFAULT_MESSAGE} More details.`, true); // false
208
+ ```
209
+
210
+ ## Public API
211
+
212
+ Import public items from the package root:
213
+
214
+ ```typescript
215
+ import {
216
+ DEFAULT_CODE,
217
+ DEFAULT_MESSAGE,
218
+ Exception,
219
+ decodeError,
220
+ encodeError,
221
+ extractMessage,
222
+ getErrorCode,
223
+ hasErrorCode,
224
+ isDefaultErrorMessage,
225
+ isEncodedError,
226
+ type IDecodedError,
227
+ type IErrorCode,
228
+ type IErrorCodeCarrier,
229
+ type IExceptionRecord,
230
+ } from 'error-message-utils';
165
231
  ```
166
232
 
233
+ ### Classes
234
+
235
+ | Export | Description |
236
+ | --- | --- |
237
+ | `Exception` | An `Error` subclass that normalizes an unknown error into `message`, `code`, and `data`. It can also serialize itself with `toString()` or `toRecord()`. |
238
+
239
+ ### Functions
167
240
 
168
- <br/>
241
+ | Export | Signature | Description |
242
+ | --- | --- | --- |
243
+ | `extractMessage` | `(error: unknown) => string` | Extracts the best readable message from strings, `Error` instances, nested error-like objects, `Error.cause` chains, arrays, plain objects, and Zod errors. Returns `DEFAULT_MESSAGE` when no useful message can be extracted. |
244
+ | `encodeError` | `(error: unknown, code: IErrorCode) => string` | Extracts a message from `error` and appends the wrapped code at the end of the message. |
245
+ | `decodeError` | `(error: unknown) => IDecodedError` | Extracts a message, resolves a code from an encoded message or code-carrying object, and returns `{ message, code, data }`. |
246
+ | `isEncodedError` | `(error: unknown) => boolean` | Returns `true` when `decodeError(error).code` resolves to a non-default code. |
247
+ | `getErrorCode` | `(error: unknown) => IErrorCode \| null` | Returns the resolved non-default code, or `null` when no non-default code is found. |
248
+ | `hasErrorCode` | `(error: unknown, code: IErrorCode) => boolean` | Checks whether an error resolves to the provided code. Raw code values are compared with strict equality. |
249
+ | `isDefaultErrorMessage` | `(value: string, fullMatch?: boolean) => boolean` | Checks whether a string contains `DEFAULT_MESSAGE`. Pass `true` as the second argument to require an exact match. |
169
250
 
170
- ## Types
251
+ ### Types
171
252
 
172
253
  ```typescript
173
- /**
174
- * Error Code
175
- * The code that is inserted when encoding an error. If none is provided or none can be extracted, it defaults to -1.
176
- */
177
254
  type IErrorCode = string | number;
178
255
 
179
- /**
180
- * Decoded Error
181
- * The object obtained when an error is decoded. Keep in mind that if the error message or the code cannot be extracted for any reason, the default values will be set instead.
182
- */
183
256
  type IDecodedError = {
184
- message: string,
185
- code: IErrorCode,
186
- };
187
-
188
- /**
189
- * Exception Record
190
- * The record type for the Exception class.
191
- */
192
- type IExceptionRecord = {
193
257
  message: string;
194
258
  code: IErrorCode;
195
259
  data: unknown | null;
196
260
  };
197
261
 
198
- /**
199
- * Error Code Carrier
200
- * An object that carries an error code, typically used to identify errors programmatically.
201
- */
202
262
  type IErrorCodeCarrier = {
203
263
  code: IErrorCode;
204
- message: string;
205
264
  } & Record<string, unknown>;
206
- ```
207
265
 
266
+ type IExceptionRecord = {
267
+ message: string;
268
+ code: IErrorCode;
269
+ data: unknown | null;
270
+ };
271
+ ```
208
272
 
209
- <br/>
273
+ | Export | Description |
274
+ | --- | --- |
275
+ | `IErrorCode` | The supported type for application error codes. |
276
+ | `IDecodedError` | The object returned by `decodeError`. |
277
+ | `IErrorCodeCarrier` | A plain object shape that can provide a code to `decodeError`, `getErrorCode`, `hasErrorCode`, and `Exception`. |
278
+ | `IExceptionRecord` | The serializable object returned by `Exception.toRecord()`. |
210
279
 
211
- ## Constants
280
+ ### Constants
212
281
 
213
282
  ```typescript
214
- // the default message if none can be extracted
215
- const DEFAULT_MESSAGE: string =
216
- 'The error message could not be extracted, check the logs for more information.';
283
+ const DEFAULT_CODE = -1;
217
284
 
218
- // the default code if none was provided or could not be extracted
219
- const DEFAULT_CODE: IErrorCode = -1;
285
+ const DEFAULT_MESSAGE =
286
+ 'The error message could not be extracted, check the logs for more information.';
220
287
  ```
221
288
 
289
+ | Export | Description |
290
+ | --- | --- |
291
+ | `DEFAULT_CODE` | The fallback code used when no code can be resolved. |
292
+ | `DEFAULT_MESSAGE` | The fallback message used when no readable message can be extracted. |
222
293
 
223
-
224
- <br/>
225
-
226
- ## Built With
227
-
228
- - TypeScript
229
-
230
-
231
-
232
-
233
- <br/>
234
-
235
- ## Running the Tests
294
+ ## Running Tests
236
295
 
237
296
  ```bash
238
- npm run test
297
+ npm test
239
298
  ```
240
299
 
241
-
242
-
243
-
244
-
245
- <br/>
246
-
247
300
  ## License
248
301
 
249
302
  [MIT](https://choosealicense.com/licenses/mit/)
@@ -1,7 +1,4 @@
1
- import type { IErrorCode, IDecodedError, IErrorCodeCarrier } from '../shared/types.js';
2
- /**
3
- * General errors
4
- */
1
+ import type { IErrorCode, IDecodedError } from '../shared/types.js';
5
2
  /**
6
3
  * Attempts to extract an error message from an error that could be anything. If it fails to do so,
7
4
  * it returns the default message.
@@ -26,6 +23,9 @@ export declare const encodeError: (error: any, code: IErrorCode) => string;
26
23
  * @returns The decoded error, containing the message and the code.
27
24
  */
28
25
  export declare const decodeError: (error: any) => IDecodedError;
26
+ /**
27
+ * Misc helpers
28
+ */
29
29
  /**
30
30
  * Determines if a given error (in any format) is an error encoded by this package.
31
31
  * @param error The error to be checked, can be of any type.
@@ -33,14 +33,11 @@ export declare const decodeError: (error: any) => IDecodedError;
33
33
  */
34
34
  export declare const isEncodedError: (error: any) => boolean;
35
35
  /**
36
- * Misc helpers
37
- */
38
- /**
39
- * Determines whether an unknown value has an inspectable error code property.
40
- * @param error The unknown value to inspect.
41
- * @returns True when the value can carry an Exception-style code.
36
+ * Retrieves the error code from a given error, or null if it matches the default code.
37
+ * @param error The error to extract the code from.
38
+ * @returns The error code or null if it matches the default code.
42
39
  */
43
- export declare const isErrorCodeCarrier: (error: unknown) => error is IErrorCodeCarrier;
40
+ export declare const getErrorCode: (error: any) => IErrorCode | null;
44
41
  /**
45
42
  * Checks if the given error matches the specified error code.
46
43
  * @param error The error to be checked, can be of any type.
@@ -1 +1 @@
1
- import{ZodError}from"zod";import{DEFAULT_CODE,DEFAULT_MESSAGE}from"../shared/constants.js";import{wrapCode,unwrapCode}from"../utils/index.js";import{extractZodErrorMessage}from"./utilities.js";export const extractMessage=r=>{if("string"==typeof r&&r.length)return r;if(r instanceof ZodError)return extractZodErrorMessage(r);if(r instanceof Error&&r.message)return r.cause?`${r.message}; [CAUSE]: ${extractMessage(r.cause)}`:r.message;if(r&&"object"==typeof r){if(r.message)return extractMessage(r.message);if(r.msg)return extractMessage(r.msg);if(r.error)return extractMessage(r.error);if(r.err)return extractMessage(r.err);if(r.errors)return extractMessage(r.errors);if(r.errs)return extractMessage(r.errs);if(r.reason)return extractMessage(r.reason);if(r.reasons)return extractMessage(r.reasons);if(r.issue)return extractMessage(r.issue);if(r.issues)return extractMessage(r.issues);if(r.data)return extractMessage(r.data);try{return JSON.stringify(r)}catch(e){console.error("Error during extractMessage:"),console.error("Original Error: ",r),console.error("JSON.stringify Error:",e)}}return DEFAULT_MESSAGE};export const encodeError=(r,e)=>`${extractMessage(r)}${wrapCode(e)}`;export const decodeError=r=>{const e=extractMessage(r),{code:s,startsAt:t}=unwrapCode(e);return{message:t>0?e.slice(0,t):e,code:s}};export const isEncodedError=r=>decodeError(r).code!==DEFAULT_CODE;export const isErrorCodeCarrier=r=>"object"==typeof r&&null!==r&&"code"in r&&("string"==typeof r.code||"number"==typeof r.code);export const hasErrorCode=(r,e)=>null!==r&&(r===e||isErrorCodeCarrier(r)&&r.code===e||decodeError(r).code===e);export const isDefaultErrorMessage=(r,e=!1)=>e?r===DEFAULT_MESSAGE:"string"==typeof r&&r.includes(DEFAULT_MESSAGE);
1
+ import{ZodError}from"zod";import{DEFAULT_CODE,DEFAULT_MESSAGE}from"../shared/constants.js";import{wrapCode,unwrapCode}from"../utils/index.js";import{extractZodErrorMessage,getDecodedErrorCode}from"./utilities.js";const __extractMessage=(r,e)=>{if("string"==typeof r&&r.length)return r;if(r instanceof ZodError)return extractZodErrorMessage(r);if(r&&"object"==typeof r){if(e.has(r))return DEFAULT_MESSAGE;e.add(r)}if(r instanceof Error&&r.message)return r.cause?`${r.message}; [CAUSE]: ${__extractMessage(r.cause,e)}`:r.message;if(r&&"object"==typeof r){if(r.message)return __extractMessage(r.message,e);if(r.msg)return __extractMessage(r.msg,e);if(r.error)return __extractMessage(r.error,e);if(r.err)return __extractMessage(r.err,e);if(r.errors)return __extractMessage(r.errors,e);if(r.errs)return __extractMessage(r.errs,e);if(r.reason)return __extractMessage(r.reason,e);if(r.reasons)return __extractMessage(r.reasons,e);if(r.issue)return __extractMessage(r.issue,e);if(r.issues)return __extractMessage(r.issues,e);if(r.data)return __extractMessage(r.data,e);try{return JSON.stringify(r)}catch(e){console.error("Error during extractMessage:"),console.error("Original Error: ",r),console.error("JSON.stringify Error:",e)}}return DEFAULT_MESSAGE};export const extractMessage=r=>__extractMessage(r,new WeakSet);export const encodeError=(r,e)=>`${extractMessage(r)}${wrapCode(e)}`;export const decodeError=r=>{const e=extractMessage(r),{code:t,startsAt:s}=unwrapCode(e);return{message:s>0?e.slice(0,s):e,code:getDecodedErrorCode(r,t),data:null!==r&&"object"==typeof r&&"data"in r?r.data:null}};export const isEncodedError=r=>decodeError(r).code!==DEFAULT_CODE;export const getErrorCode=r=>{const{code:e}=decodeError(r);return e!==DEFAULT_CODE?e:null};export const hasErrorCode=(r,e)=>null!==r&&(r===e||decodeError(r).code===e);export const isDefaultErrorMessage=(r,e=!1)=>e?r===DEFAULT_MESSAGE:"string"==typeof r&&r.includes(DEFAULT_MESSAGE);
@@ -1,4 +1,5 @@
1
1
  import { ZodError } from 'zod';
2
+ import { IErrorCode } from '../shared/types.js';
2
3
  /**
3
4
  * Attempts to extract a Zod error message from a ZodError instance. If unable to do so, it returns
4
5
  * the default error message.
@@ -6,3 +7,10 @@ import { ZodError } from 'zod';
6
7
  * @returns The extracted error message or the default message.
7
8
  */
8
9
  export declare const extractZodErrorMessage: (error: ZodError) => string;
10
+ /**
11
+ * Resolves the decoded error code from the unwrapped message code or an Exception-style object.
12
+ * @param error The unknown error object to inspect.
13
+ * @param unwrappedCode The code unwrapped from the extracted error message.
14
+ * @returns The decoded error code or the default code.
15
+ */
16
+ export declare const getDecodedErrorCode: (error: unknown, unwrappedCode: IErrorCode) => IErrorCode;
@@ -1 +1 @@
1
- import{DEFAULT_MESSAGE}from"../shared/constants.js";const __extractPathFromZodError=s=>s&&Array.isArray(s.issues)&&s.issues.length&&Array.isArray(s.issues[0].path)&&s.issues[0].path.length?s.issues[0].path.join("."):"Unknown path";export const extractZodErrorMessage=s=>s&&Array.isArray(s.issues)&&s.issues.length&&Array.isArray(s.issues[0].path)&&s.issues[0].message?`${s.issues[0].message} (${__extractPathFromZodError(s)})`:DEFAULT_MESSAGE;
1
+ import{DEFAULT_CODE,DEFAULT_MESSAGE}from"../shared/constants.js";const __extractPathFromZodError=r=>r&&Array.isArray(r.issues)&&r.issues.length&&Array.isArray(r.issues[0].path)&&r.issues[0].path.length?r.issues[0].path.join("."):"Unknown path";export const extractZodErrorMessage=r=>r&&Array.isArray(r.issues)&&r.issues.length&&Array.isArray(r.issues[0].path)&&r.issues[0].message?`${r.issues[0].message} (${__extractPathFromZodError(r)})`:DEFAULT_MESSAGE;const __isErrorCodeCarrier=r=>"object"==typeof r&&null!==r&&"code"in r&&("string"==typeof r.code||"number"==typeof r.code);export const getDecodedErrorCode=(r,s)=>s!==DEFAULT_CODE?s:__isErrorCodeCarrier(r)?r.code:DEFAULT_CODE;
@@ -1,8 +1,17 @@
1
1
  import { type IErrorCode } from '../shared/types.js';
2
- import { IExceptionRecord } from './types.js';
2
+ import { type IExceptionRecord } from './types.js';
3
+ /**
4
+ * Error subclass that normalizes unknown errors into a message, code, and optional data payload.
5
+ */
3
6
  export declare class Exception extends Error {
4
7
  readonly code: IErrorCode;
5
8
  readonly data: unknown;
9
+ /**
10
+ * Creates an exception from any supported error input.
11
+ * @param error The unknown error or message to normalize.
12
+ * @param code The optional code that overrides any decoded code.
13
+ * @param data The optional data payload that overrides any decoded data.
14
+ */
6
15
  constructor(error: unknown, code?: IErrorCode, data?: unknown);
7
16
  /**
8
17
  * Override the default toString method to return a formatted error message 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=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){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}}}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { IErrorCode, IDecodedError, IErrorCodeCarrier } from './shared/types.js';
1
+ export type { IErrorCode, IDecodedError, IErrorCodeCarrier } from './shared/types.js';
2
2
  export { DEFAULT_CODE, DEFAULT_MESSAGE } from './shared/constants.js';
3
- export { extractMessage, encodeError, decodeError, isEncodedError, isErrorCodeCarrier, hasErrorCode, isDefaultErrorMessage, } from './error-handler/index.js';
3
+ export { extractMessage, encodeError, decodeError, isEncodedError, getErrorCode, hasErrorCode, isDefaultErrorMessage, } from './error-handler/index.js';
4
4
  export { type IExceptionRecord, Exception } from './exception/index.js';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{DEFAULT_CODE,DEFAULT_MESSAGE}from"./shared/constants.js";export{extractMessage,encodeError,decodeError,isEncodedError,isErrorCodeCarrier,hasErrorCode,isDefaultErrorMessage}from"./error-handler/index.js";export{Exception}from"./exception/index.js";
1
+ export{DEFAULT_CODE,DEFAULT_MESSAGE}from"./shared/constants.js";export{extractMessage,encodeError,decodeError,isEncodedError,getErrorCode,hasErrorCode,isDefaultErrorMessage}from"./error-handler/index.js";export{Exception}from"./exception/index.js";
@@ -29,6 +29,7 @@ export type IUnwrappedErrorCode = {
29
29
  export type IDecodedError = {
30
30
  message: string;
31
31
  code: IErrorCode;
32
+ data: unknown | null;
32
33
  };
33
34
  /**
34
35
  * Error Code Carrier
@@ -37,5 +38,4 @@ export type IDecodedError = {
37
38
  */
38
39
  export type IErrorCodeCarrier = {
39
40
  code: IErrorCode;
40
- message: string;
41
41
  } & Record<string, unknown>;
@@ -1 +1 @@
1
- import{CODE_WRAPPER,DEFAULT_CODE}from"../shared/constants.js";export const wrapCode=r=>`${CODE_WRAPPER.prefix}${r??DEFAULT_CODE}${CODE_WRAPPER.suffix}`;const __isEncodedError=r=>new RegExp(`${CODE_WRAPPER.prefix}.+${CODE_WRAPPER.suffix}$`).test(r),__isNumeric=r=>"string"==typeof r&&/^[-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/.test(r);export const unwrapCode=r=>{if(__isEncodedError(r)){const E=r.lastIndexOf(CODE_WRAPPER.prefix),e=r.substring(E+CODE_WRAPPER.prefix.length,r.lastIndexOf(CODE_WRAPPER.suffix));return{code:__isNumeric(e)?Number(e):e,startsAt:E}}return{code:DEFAULT_CODE,startsAt:-1}};
1
+ import{CODE_WRAPPER,DEFAULT_CODE}from"../shared/constants.js";export const wrapCode=t=>`${CODE_WRAPPER.prefix}${t??DEFAULT_CODE}${CODE_WRAPPER.suffix}`;const __isEncodedError=t=>{const e=t.lastIndexOf(CODE_WRAPPER.prefix),r=e+CODE_WRAPPER.prefix.length,E=t.length-CODE_WRAPPER.suffix.length;return e>=0&&r<E&&t.endsWith(CODE_WRAPPER.suffix)},__isNumeric=t=>"string"==typeof t&&/^[-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/.test(t);export const unwrapCode=t=>{if(__isEncodedError(t)){const e=t.lastIndexOf(CODE_WRAPPER.prefix),r=t.substring(e+CODE_WRAPPER.prefix.length,t.lastIndexOf(CODE_WRAPPER.suffix));return{code:__isNumeric(r)?Number(r):r,startsAt:e}}return{code:DEFAULT_CODE,startsAt:-1}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "error-message-utils",
3
- "version": "1.2.9",
3
+ "version": "1.2.11",
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",