yerror 9.1.1 → 11.0.0
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/CHANGELOG.md +22 -0
- package/README.md +56 -28
- package/dist/index.d.ts +28 -20
- package/dist/index.js +57 -41
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +11 -0
- package/dist/index.test.js +109 -65
- package/dist/index.test.js.map +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +155 -71
- package/src/index.ts +97 -74
package/src/index.ts
CHANGED
|
@@ -1,36 +1,50 @@
|
|
|
1
1
|
import { EOL } from 'node:os';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export interface YErrorRegistry {
|
|
4
|
+
E_UNEXPECTED: unknown[];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type YErrorDebug<C extends string> = C extends keyof YErrorRegistry
|
|
8
|
+
? YErrorRegistry[C] extends unknown[]
|
|
9
|
+
? YErrorRegistry[C]
|
|
10
|
+
: never
|
|
11
|
+
: unknown[];
|
|
4
12
|
|
|
5
13
|
/**
|
|
6
|
-
* A YError class able to contain some
|
|
14
|
+
* A YError class able to contain some debug and
|
|
7
15
|
* print better stack traces
|
|
8
16
|
* @extends Error
|
|
9
17
|
*/
|
|
10
|
-
class YError<
|
|
18
|
+
class YError<
|
|
19
|
+
C extends string = string,
|
|
20
|
+
CC extends string = string,
|
|
21
|
+
> extends Error {
|
|
11
22
|
code: string;
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
debug: YErrorDebug<C>;
|
|
24
|
+
cause?: Error | YError<CC> | undefined;
|
|
14
25
|
/**
|
|
15
26
|
* Creates a new YError with an error code
|
|
16
|
-
* and some
|
|
27
|
+
* and some debug as debug values.
|
|
17
28
|
* @param {string} [errorCode = 'E_UNEXPECTED']
|
|
18
29
|
* The error code corresponding to the actual error
|
|
19
|
-
* @param {any} [
|
|
30
|
+
* @param {any} [debug]
|
|
20
31
|
* Some additional debugging values
|
|
32
|
+
* The error options
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* The error options
|
|
21
35
|
*/
|
|
22
36
|
constructor(
|
|
23
|
-
errorCode
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
errorCode: C = 'E_UNEXPECTED' as C,
|
|
38
|
+
debug?: YErrorDebug<C>,
|
|
39
|
+
options: { cause?: Error | YError<CC> } = {},
|
|
26
40
|
) {
|
|
27
41
|
// Call the parent constructor
|
|
28
42
|
super(errorCode);
|
|
29
43
|
|
|
30
44
|
// Filling error
|
|
31
|
-
this.code = errorCode
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
45
|
+
this.code = errorCode;
|
|
46
|
+
this.debug = (debug || []) as YErrorDebug<C>;
|
|
47
|
+
this.cause = options.cause;
|
|
34
48
|
this.name = this.toString();
|
|
35
49
|
|
|
36
50
|
if (Error.captureStackTrace) {
|
|
@@ -40,58 +54,55 @@ class YError<T extends unknown[] = YErrorDebugValue> extends Error {
|
|
|
40
54
|
|
|
41
55
|
/**
|
|
42
56
|
* Wraps any error and output a YError with an error
|
|
43
|
-
* code and some
|
|
57
|
+
* code and some debug as debug values.
|
|
44
58
|
* @param {Error} err
|
|
45
59
|
* The error to wrap
|
|
46
60
|
* @param {string} [errorCode = 'E_UNEXPECTED']
|
|
47
61
|
* The error code corresponding to the actual error
|
|
48
|
-
* @param {any} [
|
|
62
|
+
* @param {any} [debug]
|
|
49
63
|
* Some additional debugging values
|
|
50
64
|
* @return {YError}
|
|
51
65
|
* The wrapped error
|
|
52
66
|
*/
|
|
53
|
-
static wrap<
|
|
54
|
-
err: Error | YError
|
|
55
|
-
errorCode?:
|
|
56
|
-
|
|
57
|
-
): YError {
|
|
67
|
+
static wrap<C extends string, CC extends string>(
|
|
68
|
+
err: Error | YError<CC>,
|
|
69
|
+
errorCode?: C,
|
|
70
|
+
debug?: YErrorDebug<C>,
|
|
71
|
+
): YError<C, CC> {
|
|
58
72
|
const wrappedErrorIsACode = looksLikeAYErrorCode(err.message);
|
|
59
|
-
const wrappedErrors = (
|
|
60
|
-
'wrappedErrors' in err ? err.wrappedErrors : []
|
|
61
|
-
).concat([err]);
|
|
62
73
|
|
|
63
74
|
if (!errorCode) {
|
|
64
75
|
if (wrappedErrorIsACode) {
|
|
65
|
-
errorCode = err.message;
|
|
76
|
+
errorCode = err.message as C;
|
|
66
77
|
} else {
|
|
67
|
-
errorCode = 'E_UNEXPECTED';
|
|
78
|
+
errorCode = 'E_UNEXPECTED' as C;
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
return new YError
|
|
82
|
+
return new YError(errorCode, debug, { cause: err });
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
/**
|
|
75
86
|
* Return a YError as is or wraps any other error and output
|
|
76
|
-
* a YError with a code and some
|
|
87
|
+
* a YError with a code and some debug as debug values.
|
|
77
88
|
* @param {Error} err
|
|
78
89
|
* The error to cast
|
|
79
90
|
* @param {string} [errorCode = 'E_UNEXPECTED']
|
|
80
91
|
* The error code corresponding to the actual error
|
|
81
|
-
* @param {any} [
|
|
92
|
+
* @param {any} [debug]
|
|
82
93
|
* Some additional debugging values
|
|
83
94
|
* @return {YError}
|
|
84
95
|
* The wrapped error
|
|
85
96
|
*/
|
|
86
|
-
static cast<
|
|
87
|
-
err: Error | YError
|
|
88
|
-
errorCode?:
|
|
89
|
-
|
|
90
|
-
): YError {
|
|
97
|
+
static cast<C extends string, CC extends string>(
|
|
98
|
+
err: Error | YError<C> | YError<CC>,
|
|
99
|
+
errorCode?: C,
|
|
100
|
+
debug?: YErrorDebug<C>,
|
|
101
|
+
): YError<C> | YError<C, CC> {
|
|
91
102
|
if (looksLikeAYError(err)) {
|
|
92
|
-
return err
|
|
103
|
+
return err as YError<C>;
|
|
93
104
|
}
|
|
94
|
-
return YError.wrap(err, errorCode,
|
|
105
|
+
return YError.wrap<C, CC>(err, errorCode, debug);
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
/**
|
|
@@ -102,36 +113,32 @@ class YError<T extends unknown[] = YErrorDebugValue> extends Error {
|
|
|
102
113
|
* The error to bump
|
|
103
114
|
* @param {string} [errorCode = 'E_UNEXPECTED']
|
|
104
115
|
* The error code corresponding to the actual error
|
|
105
|
-
* @param {any} [
|
|
116
|
+
* @param {any} [debug]
|
|
106
117
|
* Some additional debugging values
|
|
107
118
|
* @return {YError}
|
|
108
119
|
* The wrapped error
|
|
109
120
|
*/
|
|
110
|
-
static bump<
|
|
111
|
-
err: Error | YError
|
|
112
|
-
errorCode?:
|
|
113
|
-
|
|
114
|
-
): YError {
|
|
121
|
+
static bump<C extends string, CC extends string>(
|
|
122
|
+
err: Error | YError<CC>,
|
|
123
|
+
errorCode?: C,
|
|
124
|
+
debug?: YErrorDebug<C>,
|
|
125
|
+
): YError<C, CC> | YError<CC, CC> {
|
|
115
126
|
if (looksLikeAYError(err)) {
|
|
116
|
-
return YError.wrap(err, err.code, err.
|
|
127
|
+
return YError.wrap(err, err.code as CC, err.debug as YErrorDebug<CC>);
|
|
117
128
|
}
|
|
118
|
-
return YError.wrap(err, errorCode,
|
|
129
|
+
return YError.wrap(err, errorCode, debug);
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
toString(): string {
|
|
122
|
-
let
|
|
133
|
+
let debugAsString: string;
|
|
123
134
|
|
|
124
135
|
try {
|
|
125
|
-
|
|
136
|
+
debugAsString = JSON.stringify(this.debug);
|
|
126
137
|
} catch {
|
|
127
|
-
|
|
138
|
+
debugAsString = '<circular>';
|
|
128
139
|
}
|
|
129
140
|
|
|
130
|
-
return `${
|
|
131
|
-
this.wrappedErrors.length
|
|
132
|
-
? this.wrappedErrors[this.wrappedErrors.length - 1].stack + EOL
|
|
133
|
-
: ''
|
|
134
|
-
}${this.constructor.name}: ${this.code} (${debugValuesAsString})`;
|
|
141
|
+
return `${this.constructor.name}: ${this.code} (${debugAsString})`;
|
|
135
142
|
}
|
|
136
143
|
}
|
|
137
144
|
|
|
@@ -143,14 +150,28 @@ class YError<T extends unknown[] = YErrorDebugValue> extends Error {
|
|
|
143
150
|
* @return {string}
|
|
144
151
|
* The stack trace if any
|
|
145
152
|
*/
|
|
146
|
-
export function printStackTrace(err: Error | YError): string {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
export function printStackTrace(err: Error | YError | unknown): string {
|
|
154
|
+
let errorAsString: string;
|
|
155
|
+
|
|
156
|
+
if (
|
|
157
|
+
typeof err === 'object' &&
|
|
158
|
+
err instanceof Error &&
|
|
159
|
+
typeof err.stack === 'string'
|
|
160
|
+
) {
|
|
161
|
+
errorAsString = err.stack;
|
|
162
|
+
} else {
|
|
163
|
+
try {
|
|
164
|
+
errorAsString = `[no_stack_trace]: error is serializable (${JSON.stringify(err)})`;
|
|
165
|
+
} catch {
|
|
166
|
+
errorAsString = `[no_stack_trace]: error is circular ("${
|
|
150
167
|
err != null && typeof err.toString === 'function'
|
|
151
168
|
? err.toString()
|
|
152
169
|
: typeof err
|
|
153
|
-
}`;
|
|
170
|
+
}")`;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return `${errorAsString}${err instanceof Error && err.cause ? EOL + 'Caused by: ' + printStackTrace(err.cause) : ''}`;
|
|
154
175
|
}
|
|
155
176
|
|
|
156
177
|
export function looksLikeAYErrorCode(str: string): boolean {
|
|
@@ -159,19 +180,21 @@ export function looksLikeAYErrorCode(str: string): boolean {
|
|
|
159
180
|
|
|
160
181
|
// In order to keep compatibility through major versions
|
|
161
182
|
// we have to make kind of a cross major version instanceof
|
|
162
|
-
export function looksLikeAYError(err: Error | YError): err is YError {
|
|
183
|
+
export function looksLikeAYError(err: Error | YError | unknown): err is YError {
|
|
163
184
|
return (
|
|
164
185
|
!!(err instanceof YError) ||
|
|
165
186
|
!!(
|
|
187
|
+
err &&
|
|
188
|
+
typeof err === 'object' &&
|
|
166
189
|
err.constructor &&
|
|
167
190
|
err.constructor.name &&
|
|
168
191
|
err.constructor.name.endsWith('Error') &&
|
|
169
192
|
'code' in err &&
|
|
170
193
|
'string' === typeof err.code &&
|
|
171
194
|
looksLikeAYErrorCode(err.code) &&
|
|
172
|
-
'
|
|
173
|
-
err.
|
|
174
|
-
err.
|
|
195
|
+
'debug' in err &&
|
|
196
|
+
err.debug &&
|
|
197
|
+
err.debug instanceof Array
|
|
175
198
|
)
|
|
176
199
|
);
|
|
177
200
|
}
|
|
@@ -185,10 +208,10 @@ export function looksLikeAYError(err: Error | YError): err is YError {
|
|
|
185
208
|
* @return {boolean}
|
|
186
209
|
* The result
|
|
187
210
|
*/
|
|
188
|
-
export function hasYErrorCode<
|
|
189
|
-
err: Error | YError,
|
|
190
|
-
code:
|
|
191
|
-
): err is YError<
|
|
211
|
+
export function hasYErrorCode<C extends string>(
|
|
212
|
+
err: Error | YError | unknown,
|
|
213
|
+
code: C,
|
|
214
|
+
): err is YError<C> {
|
|
192
215
|
return looksLikeAYError(err) && err.code === code;
|
|
193
216
|
}
|
|
194
217
|
|
|
@@ -201,17 +224,17 @@ export function hasYErrorCode<T extends unknown[] = YErrorDebugValue>(
|
|
|
201
224
|
* @return {boolean}
|
|
202
225
|
* The result
|
|
203
226
|
*/
|
|
204
|
-
export function pickYErrorWithCode<
|
|
205
|
-
err: Error | YError,
|
|
206
|
-
code:
|
|
207
|
-
): YError<
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (hasYErrorCode(currentError, code)) {
|
|
212
|
-
return currentError as YError<T>;
|
|
227
|
+
export function pickYErrorWithCode<C extends string>(
|
|
228
|
+
err: Error | YError | unknown,
|
|
229
|
+
code: C,
|
|
230
|
+
): YError<C> | null {
|
|
231
|
+
do {
|
|
232
|
+
if (hasYErrorCode(err, code)) {
|
|
233
|
+
return err;
|
|
213
234
|
}
|
|
214
|
-
|
|
235
|
+
err =
|
|
236
|
+
err && typeof err === 'object' && 'cause' in err && (err.cause as Error);
|
|
237
|
+
} while (err);
|
|
215
238
|
|
|
216
239
|
return null;
|
|
217
240
|
}
|