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.test.ts
CHANGED
|
@@ -1,115 +1,139 @@
|
|
|
1
1
|
import { describe, test, expect } from '@jest/globals';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
hasYErrorCode,
|
|
4
|
+
pickYErrorWithCode,
|
|
5
|
+
printStackTrace,
|
|
6
|
+
YError,
|
|
7
|
+
} from './index.js';
|
|
8
|
+
|
|
9
|
+
declare module './index.js' {
|
|
10
|
+
interface YErrorRegistry {
|
|
11
|
+
E_ERROR: `arg${number}`[];
|
|
12
|
+
E_ERROR_1: [string, string];
|
|
13
|
+
E_ERROR_2: [`arg2.1`, `arg2.2`];
|
|
14
|
+
E_ERROR_3: [`arg3.1`, `arg3.2`];
|
|
15
|
+
// Not an array will trigger type errors
|
|
16
|
+
E_ERROR_4: { foo: 'bar' };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
3
19
|
|
|
4
20
|
describe('YError', () => {
|
|
5
21
|
describe('.__constructor', () => {
|
|
6
|
-
test('
|
|
22
|
+
test('should work', () => {
|
|
7
23
|
const err = new YError('E_ERROR', ['arg1', 'arg2']);
|
|
8
24
|
|
|
9
25
|
expect(err instanceof Error).toBeTruthy();
|
|
10
26
|
expect(err.name).toEqual(err.toString());
|
|
11
27
|
expect(err.code).toEqual('E_ERROR');
|
|
12
|
-
expect(err.
|
|
28
|
+
expect(err.debug).toEqual(['arg1', 'arg2']);
|
|
13
29
|
expect(err.toString()).toEqual('YError: E_ERROR (["arg1","arg2"])');
|
|
14
30
|
});
|
|
15
|
-
test('
|
|
31
|
+
test('should work without code', () => {
|
|
16
32
|
const err = new YError();
|
|
17
33
|
|
|
18
34
|
expect(err.code).toEqual('E_UNEXPECTED');
|
|
19
|
-
expect(err.
|
|
35
|
+
expect(err.debug).toEqual([]);
|
|
20
36
|
expect(err.toString()).toEqual('YError: E_UNEXPECTED ([])');
|
|
21
37
|
expect(err.name).toEqual(err.toString());
|
|
22
38
|
});
|
|
23
|
-
test('
|
|
39
|
+
test('should work without new', () => {
|
|
24
40
|
const err = new YError('E_ERROR', ['arg1', 'arg2']);
|
|
25
41
|
|
|
26
42
|
expect(err.code).toEqual('E_ERROR');
|
|
27
43
|
expect(err instanceof YError).toBeTruthy();
|
|
28
|
-
expect(err.
|
|
44
|
+
expect(err.debug).toEqual(['arg1', 'arg2']);
|
|
29
45
|
expect(err.toString()).toEqual('YError: E_ERROR (["arg1","arg2"])');
|
|
30
46
|
expect(err.name).toEqual(err.toString());
|
|
31
47
|
});
|
|
32
48
|
});
|
|
33
49
|
|
|
34
50
|
describe('.wrap()', () => {
|
|
35
|
-
test('
|
|
36
|
-
const
|
|
51
|
+
test('should work with standard errors and a message', () => {
|
|
52
|
+
const causeErr = new Error('This is an error!');
|
|
53
|
+
const err = YError.wrap(causeErr);
|
|
37
54
|
|
|
38
55
|
expect(err.code).toEqual('E_UNEXPECTED');
|
|
39
|
-
expect(err.
|
|
40
|
-
expect(err.
|
|
56
|
+
expect(err.cause).toEqual(causeErr);
|
|
57
|
+
expect(err.debug).toEqual([]);
|
|
41
58
|
|
|
42
59
|
if ('captureStackTrace' in Error) {
|
|
43
60
|
expect(
|
|
44
|
-
-1 !== (err
|
|
61
|
+
-1 !== printStackTrace(err).indexOf('Error: This is an error!'),
|
|
45
62
|
).toBeTruthy();
|
|
46
63
|
expect(
|
|
47
|
-
-1 !==
|
|
64
|
+
-1 !==
|
|
65
|
+
printStackTrace(err).indexOf('YError: E_UNEXPECTED ([])'),
|
|
48
66
|
).toBeTruthy();
|
|
49
67
|
expect(err.name).toEqual(err.toString());
|
|
50
68
|
}
|
|
51
69
|
});
|
|
52
70
|
|
|
53
|
-
test('
|
|
54
|
-
const
|
|
71
|
+
test('should work with standard errors and an error code', () => {
|
|
72
|
+
const causeErr = new Error('E_ERROR');
|
|
73
|
+
const err = YError.wrap(causeErr);
|
|
55
74
|
|
|
56
75
|
expect(err.code).toEqual('E_ERROR');
|
|
57
|
-
expect(err.
|
|
58
|
-
expect(err.
|
|
76
|
+
expect(err.cause).toEqual(causeErr);
|
|
77
|
+
expect(err.debug).toEqual([]);
|
|
59
78
|
|
|
60
79
|
if ('captureStackTrace' in Error) {
|
|
61
|
-
expect(-1 !== (err.stack || '').indexOf('Error: E_ERROR')).toBeTruthy();
|
|
62
80
|
expect(
|
|
63
|
-
-1 !== (err
|
|
81
|
+
-1 !== printStackTrace(err).indexOf('Error: E_ERROR'),
|
|
82
|
+
).toBeTruthy();
|
|
83
|
+
expect(
|
|
84
|
+
-1 !== printStackTrace(err).indexOf('YError: E_ERROR ([])'),
|
|
64
85
|
).toBeTruthy();
|
|
65
86
|
}
|
|
66
87
|
expect(err.name).toEqual(err.toString());
|
|
67
88
|
});
|
|
68
89
|
|
|
69
|
-
test('
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
'arg2',
|
|
73
|
-
]);
|
|
90
|
+
test('should work with standard errors, an error code and params', () => {
|
|
91
|
+
const causeErr = new Error('E_ERROR');
|
|
92
|
+
const err = YError.wrap(causeErr, 'E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
74
93
|
|
|
75
94
|
expect(err.code).toEqual('E_ERROR_2');
|
|
76
|
-
expect(err.
|
|
77
|
-
expect(err.
|
|
95
|
+
expect(err.cause).toEqual(causeErr);
|
|
96
|
+
expect(err.debug).toEqual(['arg2.1', 'arg2.2']);
|
|
78
97
|
|
|
79
98
|
if ('captureStackTrace' in Error) {
|
|
80
|
-
expect(
|
|
99
|
+
expect(
|
|
100
|
+
-1 !== printStackTrace(err).indexOf('Error: E_ERROR'),
|
|
101
|
+
).toBeTruthy();
|
|
81
102
|
expect(
|
|
82
103
|
-1 !==
|
|
83
|
-
(err
|
|
104
|
+
printStackTrace(err).indexOf(
|
|
105
|
+
'YError: E_ERROR_2 (["arg2.1","arg2.2"])',
|
|
106
|
+
),
|
|
84
107
|
).toBeTruthy();
|
|
85
108
|
}
|
|
86
109
|
expect(err.name).toEqual(err.toString());
|
|
87
110
|
});
|
|
88
111
|
|
|
89
|
-
test('
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
'
|
|
93
|
-
|
|
94
|
-
);
|
|
112
|
+
test('should work with several wrapped errors', () => {
|
|
113
|
+
const causeErr1 = new Error('E_ERROR_1');
|
|
114
|
+
const causeErr2 = YError.wrap(causeErr1, 'E_ERROR_2', [
|
|
115
|
+
'arg2.1',
|
|
116
|
+
'arg2.2',
|
|
117
|
+
]);
|
|
118
|
+
const err = YError.wrap(causeErr2, 'E_ERROR_3', ['arg3.1', 'arg3.2']);
|
|
95
119
|
|
|
96
120
|
expect(err.code).toEqual('E_ERROR_3');
|
|
97
|
-
expect(err.
|
|
98
|
-
expect(err.
|
|
99
|
-
|
|
121
|
+
expect(err.cause).toEqual(causeErr2);
|
|
122
|
+
expect(err.debug).toEqual(['arg3.1', 'arg3.2']);
|
|
123
|
+
console.log(printStackTrace(err));
|
|
100
124
|
if ('captureStackTrace' in Error) {
|
|
101
125
|
expect(
|
|
102
|
-
-1 !== (err
|
|
126
|
+
-1 !== printStackTrace(err).indexOf('Error: E_ERROR_1'),
|
|
103
127
|
).toBeTruthy();
|
|
104
128
|
expect(
|
|
105
129
|
-1 !==
|
|
106
|
-
(err
|
|
130
|
+
printStackTrace(err).indexOf(
|
|
107
131
|
'YError: E_ERROR_2 (["arg2.1","arg2.2"])',
|
|
108
132
|
),
|
|
109
133
|
).toBeTruthy();
|
|
110
134
|
expect(
|
|
111
135
|
-1 !==
|
|
112
|
-
(err
|
|
136
|
+
printStackTrace(err).indexOf(
|
|
113
137
|
'YError: E_ERROR_3 (["arg3.1","arg3.2"])',
|
|
114
138
|
),
|
|
115
139
|
).toBeTruthy();
|
|
@@ -119,33 +143,38 @@ describe('YError', () => {
|
|
|
119
143
|
});
|
|
120
144
|
|
|
121
145
|
describe('.cast()', () => {
|
|
122
|
-
test('
|
|
123
|
-
const
|
|
146
|
+
test('should work with standard errors and a message', () => {
|
|
147
|
+
const causeErr = new Error('This is an error!');
|
|
148
|
+
const err = YError.cast(causeErr);
|
|
124
149
|
|
|
125
150
|
expect(err.code).toEqual('E_UNEXPECTED');
|
|
126
|
-
expect(err.
|
|
127
|
-
expect(err.
|
|
151
|
+
expect(err.cause).toEqual(causeErr);
|
|
152
|
+
expect(err.debug).toEqual([]);
|
|
128
153
|
|
|
129
154
|
if ('captureStackTrace' in Error) {
|
|
130
155
|
expect(
|
|
131
|
-
-1 !== (err
|
|
156
|
+
-1 !== printStackTrace(err).indexOf('Error: This is an error!'),
|
|
132
157
|
).toBeTruthy();
|
|
133
158
|
expect(
|
|
134
|
-
-1 !==
|
|
159
|
+
-1 !==
|
|
160
|
+
printStackTrace(err).indexOf('YError: E_UNEXPECTED ([])'),
|
|
135
161
|
).toBeTruthy();
|
|
136
162
|
}
|
|
137
163
|
expect(err.name).toEqual(err.toString());
|
|
138
164
|
});
|
|
139
165
|
|
|
140
|
-
test('
|
|
141
|
-
const
|
|
166
|
+
test('should let YError instances pass through', () => {
|
|
167
|
+
const causeErr = new YError('E_ERROR', ['arg1', 'arg2']);
|
|
168
|
+
const err = YError.cast(causeErr);
|
|
142
169
|
|
|
143
170
|
expect(err.code).toEqual('E_ERROR');
|
|
144
|
-
expect(err.
|
|
171
|
+
expect(err.cause).toBeUndefined();
|
|
172
|
+
expect(err.debug).toEqual(['arg1', 'arg2']);
|
|
145
173
|
|
|
146
174
|
if ('captureStackTrace' in Error) {
|
|
147
175
|
expect(
|
|
148
|
-
-1 !==
|
|
176
|
+
-1 !==
|
|
177
|
+
printStackTrace(err).indexOf('YError: E_ERROR (["arg1","arg2"])'),
|
|
149
178
|
).toBeTruthy();
|
|
150
179
|
}
|
|
151
180
|
expect(err.name).toEqual(err.toString());
|
|
@@ -153,43 +182,45 @@ describe('YError', () => {
|
|
|
153
182
|
});
|
|
154
183
|
|
|
155
184
|
describe('.bump()', () => {
|
|
156
|
-
test('
|
|
157
|
-
const
|
|
185
|
+
test('should work with standard errors and a message', () => {
|
|
186
|
+
const causeErr = new Error('This is an error!');
|
|
187
|
+
const err = YError.bump(causeErr);
|
|
158
188
|
|
|
159
189
|
expect(err.code).toEqual('E_UNEXPECTED');
|
|
160
|
-
expect(err.
|
|
161
|
-
expect(err.
|
|
190
|
+
expect(err.cause).toEqual(causeErr);
|
|
191
|
+
expect(err.debug).toEqual([]);
|
|
162
192
|
|
|
163
193
|
if ('captureStackTrace' in Error) {
|
|
164
194
|
expect(
|
|
165
|
-
-1 !== (err
|
|
195
|
+
-1 !== printStackTrace(err).indexOf('Error: This is an error!'),
|
|
166
196
|
).toBeTruthy();
|
|
167
197
|
expect(
|
|
168
|
-
-1 !==
|
|
198
|
+
-1 !==
|
|
199
|
+
printStackTrace(err).indexOf('YError: E_UNEXPECTED ([])'),
|
|
169
200
|
).toBeTruthy();
|
|
170
201
|
}
|
|
171
202
|
expect(err.name).toEqual(err.toString());
|
|
172
203
|
});
|
|
173
204
|
|
|
174
|
-
test('
|
|
205
|
+
test('should work with YError like errors', () => {
|
|
175
206
|
const baseErr = new Error('E_A_NEW_ERROR');
|
|
176
207
|
|
|
177
208
|
(baseErr as YError).code = 'E_A_NEW_ERROR';
|
|
178
|
-
(baseErr as YError).
|
|
209
|
+
(baseErr as YError).debug = ['baseParam1', 'baseParam2'];
|
|
179
210
|
|
|
180
211
|
const err = YError.bump(baseErr);
|
|
181
212
|
|
|
182
213
|
expect(err.code).toEqual('E_A_NEW_ERROR');
|
|
183
|
-
expect(err.
|
|
184
|
-
expect(err.
|
|
214
|
+
expect(err.cause).toEqual(baseErr);
|
|
215
|
+
expect(err.debug).toEqual(['baseParam1', 'baseParam2']);
|
|
185
216
|
|
|
186
217
|
if ('captureStackTrace' in Error) {
|
|
187
218
|
expect(
|
|
188
|
-
-1 !== (err
|
|
219
|
+
-1 !== printStackTrace(err).indexOf('Error: E_A_NEW_ERROR'),
|
|
189
220
|
).toBeTruthy();
|
|
190
221
|
expect(
|
|
191
222
|
-1 !==
|
|
192
|
-
(err
|
|
223
|
+
printStackTrace(err).indexOf(
|
|
193
224
|
'YError: E_A_NEW_ERROR (["baseParam1","baseParam2"])',
|
|
194
225
|
),
|
|
195
226
|
).toBeTruthy();
|
|
@@ -197,7 +228,7 @@ describe('YError', () => {
|
|
|
197
228
|
expect(err.name).toEqual(err.toString());
|
|
198
229
|
});
|
|
199
230
|
|
|
200
|
-
test('
|
|
231
|
+
test('should work with Y errors and a message', () => {
|
|
201
232
|
const err = YError.bump(
|
|
202
233
|
new YError('E_ERROR', ['arg1.1', 'arg1.2']),
|
|
203
234
|
'E_ERROR_2',
|
|
@@ -205,16 +236,20 @@ describe('YError', () => {
|
|
|
205
236
|
);
|
|
206
237
|
|
|
207
238
|
expect(err.code).toEqual('E_ERROR');
|
|
208
|
-
expect(err.
|
|
239
|
+
expect(err.debug).toEqual(['arg1.1', 'arg1.2']);
|
|
209
240
|
|
|
210
241
|
if ('captureStackTrace' in Error) {
|
|
211
242
|
expect(
|
|
212
243
|
-1 !==
|
|
213
|
-
(err
|
|
244
|
+
printStackTrace(err).indexOf(
|
|
245
|
+
'YError: E_ERROR (["arg1.1","arg1.2"])',
|
|
246
|
+
),
|
|
214
247
|
).toBeTruthy();
|
|
215
248
|
expect(
|
|
216
249
|
-1 !==
|
|
217
|
-
(err
|
|
250
|
+
printStackTrace(err).indexOf(
|
|
251
|
+
'YError: E_ERROR (["arg1.1","arg1.2"])',
|
|
252
|
+
),
|
|
218
253
|
).toBeTruthy();
|
|
219
254
|
}
|
|
220
255
|
expect(err.name).toEqual(err.toString());
|
|
@@ -225,13 +260,13 @@ describe('YError', () => {
|
|
|
225
260
|
test('should work with defined debug value type', () => {
|
|
226
261
|
const err = new YError('E_ERROR', ['arg1.1', 'arg1.2']);
|
|
227
262
|
|
|
228
|
-
expect(hasYErrorCode
|
|
263
|
+
expect(hasYErrorCode(err, 'E_ERROR')).toBeTruthy();
|
|
229
264
|
});
|
|
230
265
|
|
|
231
266
|
test('should work with undefined debug value type', () => {
|
|
232
|
-
const err = new YError('
|
|
267
|
+
const err = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
233
268
|
|
|
234
|
-
expect(hasYErrorCode(err, '
|
|
269
|
+
expect(hasYErrorCode(err, 'E_ERROR_2')).toBeTruthy();
|
|
235
270
|
});
|
|
236
271
|
|
|
237
272
|
test('should work with native errors', () => {
|
|
@@ -244,12 +279,61 @@ describe('YError', () => {
|
|
|
244
279
|
describe('.pickYErrorWithCode()', () => {
|
|
245
280
|
test('should work', () => {
|
|
246
281
|
const err1 = new Error('E_ERROR_1');
|
|
247
|
-
const err2 = YError.wrap(err1, 'E_ERROR_2', ['
|
|
248
|
-
const err3 = YError.wrap(err2, 'E_ERROR_3', ['
|
|
282
|
+
const err2 = YError.wrap(err1, 'E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
283
|
+
const err3 = YError.wrap(err2, 'E_ERROR_3', ['arg3.1', 'arg3.2']);
|
|
249
284
|
|
|
250
285
|
expect(pickYErrorWithCode(err3, 'E_ERROR_1')).toEqual(null);
|
|
251
286
|
expect(pickYErrorWithCode(err3, 'E_ERROR_2')).toEqual(err2);
|
|
252
287
|
expect(pickYErrorWithCode(err3, 'E_ERROR_3')).toEqual(err3);
|
|
253
288
|
});
|
|
254
289
|
});
|
|
290
|
+
|
|
291
|
+
describe('.printStackTrace()', () => {
|
|
292
|
+
test('should work with non errors', () => {
|
|
293
|
+
expect(printStackTrace('an error string')).toEqual(
|
|
294
|
+
'[no_stack_trace]: error is serializable ("an error string")',
|
|
295
|
+
);
|
|
296
|
+
expect(printStackTrace(undefined)).toEqual(
|
|
297
|
+
'[no_stack_trace]: error is serializable (undefined)',
|
|
298
|
+
);
|
|
299
|
+
expect(printStackTrace(null)).toEqual(
|
|
300
|
+
'[no_stack_trace]: error is serializable (null)',
|
|
301
|
+
);
|
|
302
|
+
expect(printStackTrace(global)).toEqual(
|
|
303
|
+
'[no_stack_trace]: error is circular ("[object Object]")',
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test('should enforce types from registry', () => {
|
|
309
|
+
// @ts-expect-error : E_ERROR_1 expects [string, string]
|
|
310
|
+
new YError('E_ERROR_1', ['only one']);
|
|
311
|
+
// Must work
|
|
312
|
+
new YError('E_WHATEVER', ['only one']);
|
|
313
|
+
new YError('E_WHATEVER', undefined);
|
|
314
|
+
new YError('E_WHATEVER');
|
|
315
|
+
|
|
316
|
+
const err = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
317
|
+
const val: 'arg2.1' | undefined = err.debug?.[0];
|
|
318
|
+
|
|
319
|
+
expect(val);
|
|
320
|
+
|
|
321
|
+
const err2 = err as YError;
|
|
322
|
+
|
|
323
|
+
// @ts-expect-error : still unknown at this level
|
|
324
|
+
const val2: 'arg2.1' = err2.debug[0];
|
|
325
|
+
|
|
326
|
+
expect(val2);
|
|
327
|
+
|
|
328
|
+
if (!hasYErrorCode(err2, 'E_ERROR_2')) {
|
|
329
|
+
throw new YError('E_UNEXPECTED');
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const val3: 'arg2.1' = err2.debug[0];
|
|
333
|
+
|
|
334
|
+
expect(val3);
|
|
335
|
+
|
|
336
|
+
// @ts-expect-error : expect error since not an array
|
|
337
|
+
new YError('E_ERROR_4', { foo: 'bar' });
|
|
338
|
+
});
|
|
255
339
|
});
|