@devp0nt/error0 1.0.0-next.45 → 1.0.0-next.47
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/cjs/index.cjs +80 -64
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +32 -22
- package/dist/cjs/plugins/cause-serialize.cjs +38 -0
- package/dist/cjs/plugins/cause-serialize.cjs.map +1 -0
- package/dist/cjs/plugins/cause-serialize.d.cts +5 -0
- package/dist/cjs/plugins/expected.cjs +49 -0
- package/dist/cjs/plugins/expected.cjs.map +1 -0
- package/dist/cjs/plugins/expected.d.cts +5 -0
- package/dist/cjs/plugins/message-merge.cjs +36 -0
- package/dist/cjs/plugins/message-merge.cjs.map +1 -0
- package/dist/cjs/plugins/message-merge.d.cts +5 -0
- package/dist/cjs/plugins/meta.cjs +73 -0
- package/dist/cjs/plugins/meta.cjs.map +1 -0
- package/dist/cjs/plugins/meta.d.cts +5 -0
- package/dist/cjs/plugins/stack-merge.cjs +39 -0
- package/dist/cjs/plugins/stack-merge.cjs.map +1 -0
- package/dist/cjs/plugins/stack-merge.d.cts +5 -0
- package/dist/cjs/plugins/tags.cjs +48 -0
- package/dist/cjs/plugins/tags.cjs.map +1 -0
- package/dist/cjs/plugins/tags.d.cts +5 -0
- package/dist/esm/index.d.ts +32 -22
- package/dist/esm/index.js +80 -64
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/plugins/cause-serialize.d.ts +5 -0
- package/dist/esm/plugins/cause-serialize.js +14 -0
- package/dist/esm/plugins/cause-serialize.js.map +1 -0
- package/dist/esm/plugins/expected.d.ts +5 -0
- package/dist/esm/plugins/expected.js +25 -0
- package/dist/esm/plugins/expected.js.map +1 -0
- package/dist/esm/plugins/message-merge.d.ts +5 -0
- package/dist/esm/plugins/message-merge.js +12 -0
- package/dist/esm/plugins/message-merge.js.map +1 -0
- package/dist/esm/plugins/meta.d.ts +5 -0
- package/dist/esm/plugins/meta.js +49 -0
- package/dist/esm/plugins/meta.js.map +1 -0
- package/dist/esm/plugins/stack-merge.d.ts +5 -0
- package/dist/esm/plugins/stack-merge.js +15 -0
- package/dist/esm/plugins/stack-merge.js.map +1 -0
- package/dist/esm/plugins/tags.d.ts +5 -0
- package/dist/esm/plugins/tags.js +24 -0
- package/dist/esm/plugins/tags.js.map +1 -0
- package/package.json +9 -1
- package/src/index.test.ts +77 -100
- package/src/index.ts +173 -120
- package/src/plugins/cause-serialize.test.ts +51 -0
- package/src/plugins/cause-serialize.ts +11 -0
- package/src/plugins/expected.test.ts +47 -0
- package/src/plugins/expected.ts +25 -0
- package/src/plugins/message-merge.test.ts +32 -0
- package/src/plugins/message-merge.ts +15 -0
- package/src/plugins/meta.test.ts +32 -0
- package/src/plugins/meta.ts +53 -0
- package/src/plugins/stack-merge.test.ts +64 -0
- package/src/plugins/stack-merge.ts +16 -0
- package/src/plugins/tags.test.ts +22 -0
- package/src/plugins/tags.ts +21 -0
package/src/index.test.ts
CHANGED
|
@@ -74,7 +74,7 @@ describe('Error0', () => {
|
|
|
74
74
|
})
|
|
75
75
|
|
|
76
76
|
it('class helpers prop/method/adapt mirror use API', () => {
|
|
77
|
-
const AppError = Error0.
|
|
77
|
+
const AppError = Error0.use('prop', 'status', {
|
|
78
78
|
init: (value: number) => value,
|
|
79
79
|
resolve: ({ own, flow }) => {
|
|
80
80
|
return typeof own === 'number' ? own : undefined
|
|
@@ -82,8 +82,8 @@ describe('Error0', () => {
|
|
|
82
82
|
serialize: ({ value }) => value,
|
|
83
83
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
84
84
|
})
|
|
85
|
-
.
|
|
86
|
-
.adapt(
|
|
85
|
+
.use('method', 'isStatus', (error, expectedStatus: number) => error.status === expectedStatus)
|
|
86
|
+
.use('adapt', (error) => {
|
|
87
87
|
if (error.cause instanceof Error && error.status === undefined) {
|
|
88
88
|
return { status: 500 }
|
|
89
89
|
}
|
|
@@ -165,7 +165,7 @@ describe('Error0', () => {
|
|
|
165
165
|
})
|
|
166
166
|
|
|
167
167
|
it('serialize uses identity by default and skips undefined plugin values', () => {
|
|
168
|
-
const AppError = Error0.use(statusPlugin).
|
|
168
|
+
const AppError = Error0.use(statusPlugin).use('prop', 'code', {
|
|
169
169
|
init: (input: string) => input,
|
|
170
170
|
resolve: ({ flow }) => flow.find(Boolean),
|
|
171
171
|
serialize: () => undefined,
|
|
@@ -185,30 +185,38 @@ describe('Error0', () => {
|
|
|
185
185
|
})
|
|
186
186
|
|
|
187
187
|
it('stack plugin can customize stack serialization without defining prop plugin', () => {
|
|
188
|
-
const AppError = Error0.stack(
|
|
188
|
+
const AppError = Error0.use('stack', { serialize: ({ value }) => (value ? `custom:${value}` : undefined) })
|
|
189
189
|
const error = new AppError('test')
|
|
190
190
|
const json = AppError.serialize(error)
|
|
191
191
|
expect(typeof json.stack).toBe('string')
|
|
192
192
|
expect((json.stack as string).startsWith('custom:')).toBe(true)
|
|
193
193
|
})
|
|
194
194
|
|
|
195
|
-
it('stack plugin
|
|
196
|
-
const AppError = Error0.stack(
|
|
195
|
+
it('stack plugin can keep default stack via identity function', () => {
|
|
196
|
+
const AppError = Error0.use('stack', { serialize: ({ value }) => value })
|
|
197
197
|
const error = new AppError('test')
|
|
198
198
|
const json = AppError.serialize(error)
|
|
199
199
|
expect(json.stack).toBe(error.stack)
|
|
200
200
|
})
|
|
201
201
|
|
|
202
|
-
it('stack plugin
|
|
203
|
-
const AppError = Error0.stack(
|
|
202
|
+
it('stack plugin can disable stack serialization via function', () => {
|
|
203
|
+
const AppError = Error0.use('stack', { serialize: () => undefined })
|
|
204
204
|
const error = new AppError('test')
|
|
205
205
|
const json = AppError.serialize(error)
|
|
206
206
|
expect('stack' in json).toBe(false)
|
|
207
207
|
})
|
|
208
208
|
|
|
209
|
+
it('stack plugin rejects boolean config', () => {
|
|
210
|
+
expect(() => Error0.use('stack', true as any)).toThrow('expects { serialize: function }')
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('message plugin rejects boolean config', () => {
|
|
214
|
+
expect(() => Error0.use('message', true as any)).toThrow('expects { serialize: function }')
|
|
215
|
+
})
|
|
216
|
+
|
|
209
217
|
it('prop("stack") throws and suggests using stack plugin', () => {
|
|
210
218
|
expect(() =>
|
|
211
|
-
Error0.
|
|
219
|
+
Error0.use('prop', 'stack', {
|
|
212
220
|
init: (input: string) => input,
|
|
213
221
|
resolve: ({ own }) => (typeof own === 'string' ? own : undefined),
|
|
214
222
|
serialize: ({ value }) => value,
|
|
@@ -228,6 +236,26 @@ describe('Error0', () => {
|
|
|
228
236
|
).toThrow('reserved prop key')
|
|
229
237
|
})
|
|
230
238
|
|
|
239
|
+
it('prop("message") throws and suggests using message plugin', () => {
|
|
240
|
+
expect(() =>
|
|
241
|
+
Error0.use('prop', 'message', {
|
|
242
|
+
resolve: ({ own }) => own as string,
|
|
243
|
+
serialize: ({ value }) => value,
|
|
244
|
+
deserialize: ({ value }) => (typeof value === 'string' ? value : undefined),
|
|
245
|
+
}),
|
|
246
|
+
).toThrow('reserved prop key')
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it('plugin builder also rejects prop("message") as reserved key', () => {
|
|
250
|
+
expect(() =>
|
|
251
|
+
Error0.plugin().prop('message', {
|
|
252
|
+
resolve: ({ own }) => own as string,
|
|
253
|
+
serialize: ({ value }) => value,
|
|
254
|
+
deserialize: ({ value }) => (typeof value === 'string' ? value : undefined),
|
|
255
|
+
}),
|
|
256
|
+
).toThrow('reserved prop key')
|
|
257
|
+
})
|
|
258
|
+
|
|
231
259
|
it('.serialize() -> .from() roundtrip keeps plugin values', () => {
|
|
232
260
|
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
233
261
|
const error = new AppError('test', { status: 409, code: 'NOT_FOUND' })
|
|
@@ -249,22 +277,12 @@ describe('Error0', () => {
|
|
|
249
277
|
expect('cause' in json).toBe(false)
|
|
250
278
|
})
|
|
251
279
|
|
|
252
|
-
it('cause plugin true serializes and deserializes nested Error0 causes', () => {
|
|
253
|
-
const AppError = Error0.use(statusPlugin).use(codePlugin).cause(true)
|
|
254
|
-
const causeError = new AppError('cause', { status: 409, code: 'NOT_FOUND' })
|
|
255
|
-
const error = new AppError('root', { status: 500, cause: causeError })
|
|
256
280
|
|
|
281
|
+
it('by default causes not serialized', () => {
|
|
282
|
+
const AppError = Error0.use(statusPlugin).use(codePlugin)
|
|
283
|
+
const error = new AppError('test', { status: 400, code: 'NOT_FOUND' })
|
|
257
284
|
const json = AppError.serialize(error, false)
|
|
258
|
-
expect(
|
|
259
|
-
expect((json.cause as Record<string, unknown>).message).toBe('cause')
|
|
260
|
-
expect((json.cause as Record<string, unknown>).status).toBe(409)
|
|
261
|
-
expect((json.cause as Record<string, unknown>).code).toBe('NOT_FOUND')
|
|
262
|
-
|
|
263
|
-
const recreated = AppError.from(json)
|
|
264
|
-
expect(recreated).toBeInstanceOf(AppError)
|
|
265
|
-
expect(recreated.cause).toBeInstanceOf(AppError)
|
|
266
|
-
expect((recreated.cause as InstanceType<typeof AppError>).status).toBe(409)
|
|
267
|
-
expect((recreated.cause as InstanceType<typeof AppError>).code).toBe('NOT_FOUND')
|
|
285
|
+
expect('cause' in json).toBe(false)
|
|
268
286
|
})
|
|
269
287
|
|
|
270
288
|
it('serialize can hide props for public output', () => {
|
|
@@ -277,7 +295,7 @@ describe('Error0', () => {
|
|
|
277
295
|
})
|
|
278
296
|
|
|
279
297
|
it('prop init without input arg infers undefined-only constructor input', () => {
|
|
280
|
-
const AppError = Error0.
|
|
298
|
+
const AppError = Error0.use('prop', 'computed', {
|
|
281
299
|
init: () => undefined as number | undefined,
|
|
282
300
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
283
301
|
serialize: ({ value }) => value,
|
|
@@ -294,7 +312,7 @@ describe('Error0', () => {
|
|
|
294
312
|
})
|
|
295
313
|
|
|
296
314
|
it('prop without init omits constructor input and infers resolve output', () => {
|
|
297
|
-
const AppError = Error0.
|
|
315
|
+
const AppError = Error0.use('prop', 'statusCode', {
|
|
298
316
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
299
317
|
serialize: ({ value }) => value,
|
|
300
318
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
@@ -310,7 +328,7 @@ describe('Error0', () => {
|
|
|
310
328
|
})
|
|
311
329
|
|
|
312
330
|
it('prop output type is inferred from resolve type', () => {
|
|
313
|
-
const AppError = Error0.
|
|
331
|
+
const AppError = Error0.use('prop', 'x', {
|
|
314
332
|
init: (input: number) => input,
|
|
315
333
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number') || 500,
|
|
316
334
|
serialize: ({ value }) => value,
|
|
@@ -323,7 +341,7 @@ describe('Error0', () => {
|
|
|
323
341
|
expectTypeOf(AppError.own(error, 'x')).toEqualTypeOf<number | undefined>()
|
|
324
342
|
expectTypeOf(AppError.flow(error, 'x')).toEqualTypeOf<Array<number | undefined>>()
|
|
325
343
|
|
|
326
|
-
Error0.prop('x', {
|
|
344
|
+
Error0.plugin().prop('x', {
|
|
327
345
|
init: (input: number) => input,
|
|
328
346
|
// @ts-expect-error - resolve type extends init type
|
|
329
347
|
resolve: ({ flow }) => 'string',
|
|
@@ -333,7 +351,7 @@ describe('Error0', () => {
|
|
|
333
351
|
})
|
|
334
352
|
|
|
335
353
|
it('own/flow are typed by output type, not resolve type', () => {
|
|
336
|
-
const AppError = Error0.
|
|
354
|
+
const AppError = Error0.use('prop', 'code', {
|
|
337
355
|
init: (input: number | 'fallback') => input,
|
|
338
356
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number') ?? 500,
|
|
339
357
|
serialize: ({ value }) => value,
|
|
@@ -354,12 +372,12 @@ describe('Error0', () => {
|
|
|
354
372
|
it('own/flow runtime behavior across causes', () => {
|
|
355
373
|
type Code = 'A' | 'B'
|
|
356
374
|
const isCode = (item: unknown): item is Code => item === 'A' || item === 'B'
|
|
357
|
-
const AppError = Error0.
|
|
375
|
+
const AppError = Error0.use('prop', 'status', {
|
|
358
376
|
init: (input: number) => input,
|
|
359
377
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
360
378
|
serialize: ({ value }) => value,
|
|
361
379
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
362
|
-
}).
|
|
380
|
+
}).use('prop', 'code', {
|
|
363
381
|
init: (input: Code) => input,
|
|
364
382
|
resolve: ({ flow }) => flow.find(isCode),
|
|
365
383
|
serialize: ({ value }) => value,
|
|
@@ -381,12 +399,12 @@ describe('Error0', () => {
|
|
|
381
399
|
it('own/flow have strong types for static and instance methods', () => {
|
|
382
400
|
type Code = 'A' | 'B'
|
|
383
401
|
const isCode = (item: unknown): item is Code => item === 'A' || item === 'B'
|
|
384
|
-
const AppError = Error0.
|
|
402
|
+
const AppError = Error0.use('prop', 'status', {
|
|
385
403
|
init: (input: number) => input,
|
|
386
404
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
387
405
|
serialize: ({ value }) => value,
|
|
388
406
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
389
|
-
}).
|
|
407
|
+
}).use('prop', 'code', {
|
|
390
408
|
init: (input: Code) => input,
|
|
391
409
|
resolve: ({ flow }) => flow.find(isCode),
|
|
392
410
|
serialize: ({ value }) => value,
|
|
@@ -408,19 +426,19 @@ describe('Error0', () => {
|
|
|
408
426
|
it('resolve returns plain resolved props object without methods', () => {
|
|
409
427
|
type Code = 'A' | 'B'
|
|
410
428
|
const isCode = (item: unknown): item is Code => item === 'A' || item === 'B'
|
|
411
|
-
const AppError = Error0.
|
|
429
|
+
const AppError = Error0.use('prop', 'status', {
|
|
412
430
|
init: (input: number) => input,
|
|
413
431
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number') ?? 500,
|
|
414
432
|
serialize: ({ value }) => value,
|
|
415
433
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
416
434
|
})
|
|
417
|
-
.
|
|
435
|
+
.use('prop', 'code', {
|
|
418
436
|
init: (input: Code) => input,
|
|
419
437
|
resolve: ({ flow }) => flow.find(isCode),
|
|
420
438
|
serialize: ({ value }) => value,
|
|
421
439
|
deserialize: ({ value }) => (value === 'A' || value === 'B' ? value : undefined),
|
|
422
440
|
})
|
|
423
|
-
.
|
|
441
|
+
.use('method', 'isStatus', (error, status: number) => error.status === status)
|
|
424
442
|
|
|
425
443
|
const root = new AppError('root', { status: 400, code: 'A' })
|
|
426
444
|
const leaf = new AppError('leaf', { cause: root })
|
|
@@ -436,7 +454,7 @@ describe('Error0', () => {
|
|
|
436
454
|
})
|
|
437
455
|
|
|
438
456
|
it('prop resolved type can be not undefined with init not provided', () => {
|
|
439
|
-
const AppError = Error0.
|
|
457
|
+
const AppError = Error0.use('prop', 'x', {
|
|
440
458
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number') || 500,
|
|
441
459
|
serialize: ({ value }) => value,
|
|
442
460
|
deserialize: ({ value }) => (typeof value === 'number' ? value : undefined),
|
|
@@ -446,7 +464,7 @@ describe('Error0', () => {
|
|
|
446
464
|
expect(error.x).toBe(500)
|
|
447
465
|
expectTypeOf<typeof error.x>().toEqualTypeOf<number>()
|
|
448
466
|
|
|
449
|
-
Error0.prop('x', {
|
|
467
|
+
Error0.plugin().prop('x', {
|
|
450
468
|
init: (input: number) => input,
|
|
451
469
|
// @ts-expect-error - resolve type extends init type
|
|
452
470
|
resolve: ({ flow }) => 'string',
|
|
@@ -456,7 +474,7 @@ describe('Error0', () => {
|
|
|
456
474
|
})
|
|
457
475
|
|
|
458
476
|
it('serialize/deserialize can be set to false to disable them', () => {
|
|
459
|
-
const AppError = Error0.
|
|
477
|
+
const AppError = Error0.use('prop', 'status', {
|
|
460
478
|
init: (input: number) => input,
|
|
461
479
|
resolve: ({ flow }) => flow.find((item) => typeof item === 'number'),
|
|
462
480
|
serialize: false,
|
|
@@ -516,7 +534,7 @@ describe('Error0', () => {
|
|
|
516
534
|
assert.ok(parsedError)
|
|
517
535
|
const AppError = Error0.use(statusPlugin)
|
|
518
536
|
.use(codePlugin)
|
|
519
|
-
.adapt(
|
|
537
|
+
.use('adapt', (error) => {
|
|
520
538
|
if (error.cause instanceof ZodError) {
|
|
521
539
|
error.message = `Validation Error: ${error.message}`
|
|
522
540
|
return {
|
|
@@ -536,41 +554,19 @@ describe('Error0', () => {
|
|
|
536
554
|
expect(error1.code).toBe(undefined)
|
|
537
555
|
})
|
|
538
556
|
|
|
539
|
-
it('expected prop can be realized to send or not to send error to your error tracker', () => {
|
|
540
|
-
const AppError = Error0.use(statusPlugin)
|
|
541
|
-
.prop('expected', {
|
|
542
|
-
init: (input: boolean) => input,
|
|
543
|
-
resolve: ({ flow }) => flow.find((value) => typeof value === 'boolean'),
|
|
544
|
-
serialize: ({ value }) => value,
|
|
545
|
-
deserialize: ({ value }) => (typeof value === 'boolean' ? value : undefined),
|
|
546
|
-
})
|
|
547
|
-
.method('isExpected', (error) => {
|
|
548
|
-
return error.expected ?? false
|
|
549
|
-
})
|
|
550
|
-
const errorExpected = new AppError('test', { status: 400, expected: true })
|
|
551
|
-
const errorUnexpected = new AppError('test', { status: 400, expected: false })
|
|
552
|
-
const usualError = new Error('test')
|
|
553
|
-
const errorFromUsualError = AppError.from(usualError)
|
|
554
|
-
const errorWithExpectedErrorAsCause = new AppError('test', { status: 400, cause: errorExpected })
|
|
555
|
-
const errorWithUnexpectedErrorAsCause = new AppError('test', { status: 400, cause: errorUnexpected })
|
|
556
|
-
expect(errorExpected.expected).toBe(true)
|
|
557
|
-
expect(errorUnexpected.expected).toBe(false)
|
|
558
|
-
expect(AppError.isExpected(usualError)).toBe(false)
|
|
559
|
-
expect(errorFromUsualError.expected).toBe(undefined)
|
|
560
|
-
expect(errorFromUsualError.isExpected()).toBe(false)
|
|
561
|
-
expect(errorWithExpectedErrorAsCause.expected).toBe(true)
|
|
562
|
-
expect(errorWithExpectedErrorAsCause.isExpected()).toBe(true)
|
|
563
|
-
expect(errorWithUnexpectedErrorAsCause.expected).toBe(false)
|
|
564
|
-
expect(errorWithUnexpectedErrorAsCause.isExpected()).toBe(false)
|
|
565
|
-
})
|
|
566
557
|
|
|
567
558
|
it('messages can be combined on serialization', () => {
|
|
568
559
|
const AppError = Error0.use(statusPlugin)
|
|
569
560
|
.use(codePlugin)
|
|
570
|
-
.
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
561
|
+
.use('message', {
|
|
562
|
+
serialize: ({ error }) =>
|
|
563
|
+
error
|
|
564
|
+
.causes()
|
|
565
|
+
.map((cause) => {
|
|
566
|
+
return cause instanceof Error ? cause.message : undefined
|
|
567
|
+
})
|
|
568
|
+
.filter((value): value is string => typeof value === 'string')
|
|
569
|
+
.join(': '),
|
|
574
570
|
})
|
|
575
571
|
const error1 = new AppError('test1', { status: 400, code: 'NOT_FOUND' })
|
|
576
572
|
const error2 = new AppError({ message: 'test2', status: 401, cause: error1 })
|
|
@@ -584,15 +580,16 @@ describe('Error0', () => {
|
|
|
584
580
|
it('stack plugin can merge stack across causes in one serialized value', () => {
|
|
585
581
|
const AppError = Error0.use(statusPlugin)
|
|
586
582
|
.use(codePlugin)
|
|
587
|
-
.stack
|
|
588
|
-
error
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
583
|
+
.use('stack', {
|
|
584
|
+
serialize: ({ error }) =>
|
|
585
|
+
error
|
|
586
|
+
.causes()
|
|
587
|
+
.map((cause) => {
|
|
588
|
+
return cause instanceof Error ? cause.stack : undefined
|
|
589
|
+
})
|
|
590
|
+
.filter((value): value is string => typeof value === 'string')
|
|
591
|
+
.join('\n'),
|
|
592
|
+
})
|
|
596
593
|
const error1 = new AppError('test1', { status: 400, code: 'NOT_FOUND' })
|
|
597
594
|
const error2 = new AppError('test2', { status: 401, cause: error1 })
|
|
598
595
|
const mergedStack1 = error1.serialize().stack as string
|
|
@@ -612,26 +609,6 @@ describe('Error0', () => {
|
|
|
612
609
|
`)
|
|
613
610
|
})
|
|
614
611
|
|
|
615
|
-
it('stack plugin can merge stack across causes in one serialized value by helper "merge"', () => {
|
|
616
|
-
const AppError = Error0.use(statusPlugin).use(codePlugin).stack('merge')
|
|
617
|
-
const error1 = new AppError('test1', { status: 400, code: 'NOT_FOUND' })
|
|
618
|
-
const error2 = new AppError('test2', { status: 401, cause: error1 })
|
|
619
|
-
const mergedStack1 = error1.serialize().stack as string
|
|
620
|
-
const mergedStack2 = error2.serialize().stack as string
|
|
621
|
-
expect(mergedStack1).toContain('Error0: test1')
|
|
622
|
-
expect(mergedStack2).toContain('Error0: test2')
|
|
623
|
-
expect(mergedStack2).toContain('Error0: test1')
|
|
624
|
-
expect(fixStack(mergedStack1)).toMatchInlineSnapshot(`
|
|
625
|
-
"Error0: test1
|
|
626
|
-
at <anonymous> (...)"
|
|
627
|
-
`)
|
|
628
|
-
expect(fixStack(mergedStack2)).toMatchInlineSnapshot(`
|
|
629
|
-
"Error0: test2
|
|
630
|
-
at <anonymous> (...)
|
|
631
|
-
Error0: test1
|
|
632
|
-
at <anonymous> (...)"
|
|
633
|
-
`)
|
|
634
|
-
})
|
|
635
612
|
|
|
636
613
|
it('Error0 assignable to LikeError0', () => {
|
|
637
614
|
type LikeError0 = {
|