@nest-yalc-2/errors 2.2.1 → 2.2.3
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/package.json +16 -8
- package/src/__tests__/database-exception.filter.spec.ts +71 -71
- package/src/__tests__/http-exception.filter.spec.ts +182 -182
- package/src/__tests__/system-exception.filter.spec.ts +39 -39
- package/src/__tests__/validation-exception.filter.spec.ts +31 -31
- package/src/filters/database-exception.filter.ts +45 -45
- package/src/filters/http-exception.filter.ts +144 -144
- package/src/filters/index.ts +6 -6
- package/src/filters/system-exception.filter.ts +13 -13
- package/src/filters/validation-exception.filter.ts +26 -26
- package/src/index.ts +8 -8
- package/src/__tests__/default.error.spec.ts +0 -529
- package/src/__tests__/error.helper.spec.ts +0 -23
- package/src/__tests__/errors.enum.spec.ts +0 -32
- package/src/__tests__/http-status-code-to-errors.spec.ts +0 -26
- package/src/__tests__/input-validation.error.spec.ts +0 -27
- package/src/__tests__/login.error.spec.ts +0 -23
- package/src/__tests__/result.error.spec.ts +0 -47
- package/src/__tests__/verification.error.spec.ts +0 -28
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, jest } from '@jest/globals';
|
|
2
|
-
import {
|
|
3
|
-
DefaultError,
|
|
4
|
-
DefaultErrorMixin,
|
|
5
|
-
ON_DEFAULT_ERROR_EVENT,
|
|
6
|
-
newDefaultError,
|
|
7
|
-
isDefaultErrorMixin,
|
|
8
|
-
DefaultErrorBase,
|
|
9
|
-
errorToDefaultError,
|
|
10
|
-
isDefaultErrorMixinClass,
|
|
11
|
-
} from '../default.error.js';
|
|
12
|
-
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
13
|
-
import EventEmitter from 'events';
|
|
14
|
-
import {
|
|
15
|
-
BadRequestException,
|
|
16
|
-
ForbiddenException,
|
|
17
|
-
HttpException,
|
|
18
|
-
HttpStatus,
|
|
19
|
-
} from '@nestjs/common';
|
|
20
|
-
import { getHttpStatusDescription } from '@node-yalc/utils/http.helper.js';
|
|
21
|
-
|
|
22
|
-
describe('DefaultErrorMixin', () => {
|
|
23
|
-
it('should create a class that extends Error when no base class is provided', () => {
|
|
24
|
-
const error = new (DefaultErrorMixin())({}, 'message', 500);
|
|
25
|
-
expect(error).toBeInstanceOf(Error);
|
|
26
|
-
expect(error.message).toBe('message');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should create a class that extends the provided base class', () => {
|
|
30
|
-
class CustomError extends HttpException {}
|
|
31
|
-
const error = new (DefaultErrorMixin(CustomError))({}, 'message', 500);
|
|
32
|
-
expect(error).toBeInstanceOf(CustomError);
|
|
33
|
-
expect(error.message).toBe('message');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should set internalMessage when options is a string', () => {
|
|
37
|
-
const error = new (DefaultErrorMixin())(
|
|
38
|
-
{ internalMessage: 'internalMessage' },
|
|
39
|
-
{},
|
|
40
|
-
500,
|
|
41
|
-
);
|
|
42
|
-
expect(error.internalMessage).toBe('internalMessage');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should set data when data option is provided', () => {
|
|
46
|
-
const error = new (DefaultErrorMixin())({ data: 'data' }, 'message', 500);
|
|
47
|
-
expect(error.data).toBe('data'); // Note: You might want to mock `maskDataInObject` to test this
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should set data when masked data option is provided', () => {
|
|
51
|
-
const error = new (DefaultErrorMixin())(
|
|
52
|
-
{ data: { test: 'test' }, masks: ['test'] },
|
|
53
|
-
'message',
|
|
54
|
-
500,
|
|
55
|
-
);
|
|
56
|
-
expect(error.data).toEqual({ test: '[REDACTED]' });
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should set internalMessage when internalMessage option is provided', () => {
|
|
60
|
-
const error = new (DefaultErrorMixin())(
|
|
61
|
-
{
|
|
62
|
-
internalMessage: 'internalMessage',
|
|
63
|
-
},
|
|
64
|
-
'message',
|
|
65
|
-
500,
|
|
66
|
-
);
|
|
67
|
-
expect(error.internalMessage).toBe('internalMessage');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should log error when logger option is provided', () => {
|
|
71
|
-
const logger = { error: jest.fn() };
|
|
72
|
-
const error = new (DefaultErrorMixin())(
|
|
73
|
-
{ logger: { instance: logger, level: 'error' } },
|
|
74
|
-
'message',
|
|
75
|
-
500,
|
|
76
|
-
);
|
|
77
|
-
expect(logger.error).toHaveBeenCalled();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should use console as logger when logger option is true', () => {
|
|
81
|
-
const logger = { error: jest.fn() };
|
|
82
|
-
const error = new (DefaultErrorMixin())({ logger: {} }, 'message', 500);
|
|
83
|
-
// expect(logger.error).toHaveBeenCalled();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should emit an event when eventEmitter option is provided', () => {
|
|
87
|
-
const eventEmitter = new EventEmitter();
|
|
88
|
-
const eventHandler = jest.fn();
|
|
89
|
-
eventEmitter.on(ON_DEFAULT_ERROR_EVENT, eventHandler);
|
|
90
|
-
const error = new (DefaultErrorMixin())({ eventEmitter }, 'message');
|
|
91
|
-
expect(eventHandler).toHaveBeenCalled();
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should emit an event when eventEmitter2 option is provided', () => {
|
|
95
|
-
const eventEmitter = new EventEmitter2();
|
|
96
|
-
const eventHandler = jest.fn();
|
|
97
|
-
eventEmitter.on(ON_DEFAULT_ERROR_EVENT, eventHandler);
|
|
98
|
-
const error = new (DefaultErrorMixin())({ eventEmitter }, 'message', 500);
|
|
99
|
-
expect(eventHandler).toHaveBeenCalled();
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should not emit an event when eventEmitter option is false', () => {
|
|
103
|
-
const error = new (DefaultErrorMixin())(
|
|
104
|
-
{ eventEmitter: false },
|
|
105
|
-
'message',
|
|
106
|
-
500,
|
|
107
|
-
);
|
|
108
|
-
expect(error.eventEmitter).toBeUndefined();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('newDefaultError', () => {
|
|
113
|
-
it('should create a new DefaultError class instance that extends the provided base class', () => {
|
|
114
|
-
class CustomError extends HttpException {}
|
|
115
|
-
const error = newDefaultError(CustomError, {}, 'message', 500);
|
|
116
|
-
expect(error).toBeInstanceOf(CustomError);
|
|
117
|
-
expect(error.message).toBe('message');
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
describe('DefaultError', () => {
|
|
122
|
-
it('should create an instance of Error', () => {
|
|
123
|
-
const error = new DefaultError('my internal message', {
|
|
124
|
-
response: 'my external message',
|
|
125
|
-
logger: true,
|
|
126
|
-
});
|
|
127
|
-
expect(error).toBeInstanceOf(Error);
|
|
128
|
-
expect(error.message).toBe('my external message');
|
|
129
|
-
expect(error.internalMessage).toBe('my internal message');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should be able to use the setErrorInfo method', () => {
|
|
133
|
-
const error = new DefaultError('my internal message', {
|
|
134
|
-
logger: true,
|
|
135
|
-
});
|
|
136
|
-
error.setErrorInfo({ data: 'test error info' });
|
|
137
|
-
expect(error.getEventPayload()).toMatchObject({ data: 'test error info' });
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('should be able to use the mergeErrorInfo method', () => {
|
|
141
|
-
const error = new DefaultError('my internal message', {
|
|
142
|
-
logger: true,
|
|
143
|
-
});
|
|
144
|
-
error.mergeErrorInfo({
|
|
145
|
-
data: { test: 'test error info' },
|
|
146
|
-
response: { message: 'test error response' },
|
|
147
|
-
cause: new Error('test cause'),
|
|
148
|
-
internalMessage: 'test internal message',
|
|
149
|
-
description: 'test description',
|
|
150
|
-
eventName: 'test event name',
|
|
151
|
-
stack: 'test stack',
|
|
152
|
-
});
|
|
153
|
-
expect(error.getEventPayload()).toMatchObject({
|
|
154
|
-
data: { test: 'test error info' },
|
|
155
|
-
message: 'test error response',
|
|
156
|
-
cause: expect.anything(),
|
|
157
|
-
internalMessage: 'test internal message',
|
|
158
|
-
description: 'test description',
|
|
159
|
-
eventName: 'test event name',
|
|
160
|
-
stack: 'test stack',
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should be able to cover the mergeErrorInfo method', () => {
|
|
165
|
-
const error = new DefaultError('my internal message', {
|
|
166
|
-
logger: true,
|
|
167
|
-
description: undefined,
|
|
168
|
-
response: undefined,
|
|
169
|
-
});
|
|
170
|
-
error.mergeErrorInfo({
|
|
171
|
-
data: { test: 'test error info' },
|
|
172
|
-
});
|
|
173
|
-
expect(error.getEventPayload()).toMatchObject({
|
|
174
|
-
data: { test: 'test error info' },
|
|
175
|
-
message: 'Default Error',
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('should merge error info without replacing data when no data is provided', () => {
|
|
180
|
-
const error = new DefaultError('my internal message', {
|
|
181
|
-
data: { existing: true },
|
|
182
|
-
});
|
|
183
|
-
error.mergeErrorInfo({
|
|
184
|
-
response: { message: 'updated response' },
|
|
185
|
-
});
|
|
186
|
-
expect(error.getEventPayload()).toMatchObject({
|
|
187
|
-
data: { existing: true },
|
|
188
|
-
message: 'updated response',
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it('should create an instance of Error with default message when message is not provided', () => {
|
|
193
|
-
const error = new DefaultError();
|
|
194
|
-
expect(error).toBeInstanceOf(Error);
|
|
195
|
-
expect(error.message).toBe('Default Error'); // if not specified, the message will be the parsed name of the class
|
|
196
|
-
expect(error.internalMessage).toBeUndefined();
|
|
197
|
-
expect(`${error}`.startsWith(`Default Error -`)).toBeTruthy();
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('should create an instance of Error with default options when options are not provided', () => {
|
|
201
|
-
const error = new DefaultError('message');
|
|
202
|
-
expect(error).toBeInstanceOf(Error);
|
|
203
|
-
expect(error.message).toBe('Default Error');
|
|
204
|
-
expect(error.internalMessage).toBe('message');
|
|
205
|
-
expect(error.data).toBeUndefined();
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it('should create a DefaultErrorBase without base class', () => {
|
|
209
|
-
const error = new (DefaultErrorBase())();
|
|
210
|
-
expect(error.message).toBe('Error');
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('should create an instance of Error with response as a string', () => {
|
|
214
|
-
const error = new DefaultError('message', {
|
|
215
|
-
response: 'my response',
|
|
216
|
-
logger: {
|
|
217
|
-
level: 'log',
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
|
-
expect(error).toBeInstanceOf(Error);
|
|
221
|
-
expect(error.getResponse().message).toBe('my response');
|
|
222
|
-
expect(error.getInternalMessage()).toBe('message');
|
|
223
|
-
expect(error.getDescription()).toBe(getHttpStatusDescription(500));
|
|
224
|
-
expect(error.getEventPayload()).toEqual(expect.anything());
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should create an instance of Error with response as an object', () => {
|
|
228
|
-
const error = new DefaultError('message', {
|
|
229
|
-
response: { message: 'ok', test: 'test' },
|
|
230
|
-
});
|
|
231
|
-
expect(error).toBeInstanceOf(Error);
|
|
232
|
-
expect(error.getResponse().message).toBe('ok');
|
|
233
|
-
expect(error.getResponse().test).toBe('test');
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('should create an instance of Error without options', () => {
|
|
237
|
-
const error = new DefaultError();
|
|
238
|
-
expect(error).toBeInstanceOf(HttpException);
|
|
239
|
-
expect(error.getResponse().message).toBe('Default Error');
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should create an instance of Error without defaultError options', () => {
|
|
243
|
-
const error = new DefaultError('internal test message', {
|
|
244
|
-
description: 'this description should go in the info',
|
|
245
|
-
data: { test: 'this property should go in the info' },
|
|
246
|
-
});
|
|
247
|
-
expect(error).toBeInstanceOf(HttpException);
|
|
248
|
-
expect(error.getResponse().message).toBe('Default Error');
|
|
249
|
-
expect(`${error}`.startsWith('internal test message -')).toBeTruthy();
|
|
250
|
-
expect(
|
|
251
|
-
`${error}`.includes('this description should go in the info'),
|
|
252
|
-
).toBeTruthy();
|
|
253
|
-
expect(
|
|
254
|
-
`${error}`.includes('this property should go in the info'),
|
|
255
|
-
).toBeTruthy();
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should create an instance of the Error with options as a string', () => {
|
|
259
|
-
const error = new (DefaultErrorMixin())(
|
|
260
|
-
{ internalMessage: 'internal' },
|
|
261
|
-
'external',
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
expect(error.getResponse().message).toBe('external');
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
describe('isDefaultErrorMixin', () => {
|
|
268
|
-
it('should check if an error is not of DefaultMixin type', () => {
|
|
269
|
-
const check = isDefaultErrorMixin({});
|
|
270
|
-
expect(check).toBeFalsy();
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('should check if an error is of DefaultMixin type', () => {
|
|
274
|
-
const error = new DefaultError();
|
|
275
|
-
const check = isDefaultErrorMixin(error);
|
|
276
|
-
expect(check).toBeTruthy();
|
|
277
|
-
});
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
describe('isDefaultErrorMixinClass', () => {
|
|
281
|
-
it('should check if an error is not of DefaultMixin type', () => {
|
|
282
|
-
const check = isDefaultErrorMixinClass(BadRequestException);
|
|
283
|
-
expect(check).toBeFalsy();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
it('should check if an error is of DefaultMixin type', () => {
|
|
287
|
-
const check = isDefaultErrorMixinClass(DefaultError);
|
|
288
|
-
expect(check).toBeTruthy();
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
describe('error cause', () => {
|
|
293
|
-
it('should return if no cause defined', () => {
|
|
294
|
-
const check = new DefaultError('test', { cause: undefined });
|
|
295
|
-
expect(check.cause).toBeUndefined();
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
it('should return if cause is defined', () => {
|
|
299
|
-
const check = new DefaultError('test', { cause: new Error('test') });
|
|
300
|
-
expect(check.getEventPayload().cause).toBeDefined();
|
|
301
|
-
expect(check.getEventPayload().cause?.parentCause).toBeUndefined();
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it('should have multiple causes', () => {
|
|
305
|
-
const check = new DefaultError('test', {
|
|
306
|
-
cause: new DefaultError('test', { cause: { nonErrorCause: '' } }),
|
|
307
|
-
});
|
|
308
|
-
expect(check.cause).toBeDefined();
|
|
309
|
-
expect(check.getEventPayload().cause?.parentCause).toBeDefined();
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
describe('errorToDefaultError', () => {
|
|
314
|
-
it.each([
|
|
315
|
-
{ name: 'standard Error', value: new Error('test') },
|
|
316
|
-
{ name: 'HttpException', value: new HttpException('test', 500) },
|
|
317
|
-
{ name: 'DefaultError', value: new DefaultError('test') },
|
|
318
|
-
{ name: 'string', value: 'test' as unknown as Error },
|
|
319
|
-
{
|
|
320
|
-
name: 'object with message',
|
|
321
|
-
value: { message: 'test' } as unknown as Error,
|
|
322
|
-
},
|
|
323
|
-
{ name: 'empty object', value: {} as unknown as Error },
|
|
324
|
-
{ name: 'null', value: null as unknown as Error },
|
|
325
|
-
{ name: 'undefined', value: undefined as unknown as Error },
|
|
326
|
-
{ name: 'number', value: 123 as unknown as Error },
|
|
327
|
-
{ name: 'boolean', value: true as unknown as Error },
|
|
328
|
-
{ name: 'array', value: [] as unknown as Error },
|
|
329
|
-
{
|
|
330
|
-
name: 'nested error',
|
|
331
|
-
value: { error: new Error('nested') } as unknown as Error,
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
name: 'error with circular reference',
|
|
335
|
-
value: (() => {
|
|
336
|
-
const err: any = new Error('circular');
|
|
337
|
-
err.self = err;
|
|
338
|
-
return err;
|
|
339
|
-
})(),
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
name: 'error with custom properties',
|
|
343
|
-
value: Object.assign(new Error('custom'), { custom: 'property' }),
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
name: 'BadRequestException',
|
|
347
|
-
value: new BadRequestException('bad request'),
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
name: 'ForbiddenException',
|
|
351
|
-
value: new ForbiddenException('forbidden'),
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
name: 'undefined with no prototype',
|
|
355
|
-
value: Object.create(null) as unknown as Error,
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
name: 'object with null prototype that mimics Error',
|
|
359
|
-
value: Object.assign(Object.create(null), {
|
|
360
|
-
message: 'test',
|
|
361
|
-
name: 'FakeError',
|
|
362
|
-
stack: 'fake stack',
|
|
363
|
-
}) as unknown as Error,
|
|
364
|
-
},
|
|
365
|
-
// These test method invocation problems with HttpException-like objects
|
|
366
|
-
{
|
|
367
|
-
name: 'fake HttpException with broken getStatus',
|
|
368
|
-
value: Object.assign(new Error('test'), {
|
|
369
|
-
getStatus: () => {
|
|
370
|
-
throw new Error('getStatus exploded');
|
|
371
|
-
},
|
|
372
|
-
getResponse: () => ({ toString: () => 'response' }),
|
|
373
|
-
}),
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
name: 'fake HttpException with broken getResponse',
|
|
377
|
-
value: Object.assign(new Error('test'), {
|
|
378
|
-
getStatus: () => 500,
|
|
379
|
-
getResponse: () => {
|
|
380
|
-
throw new Error('getResponse exploded');
|
|
381
|
-
},
|
|
382
|
-
}),
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
name: 'deeply nested circular reference',
|
|
386
|
-
value: (() => {
|
|
387
|
-
const err: any = new Error('deep circular');
|
|
388
|
-
const nested = { parent: err, child: {} };
|
|
389
|
-
err.nested = nested;
|
|
390
|
-
// @ts-expect-error - this is a test
|
|
391
|
-
nested.child.backRef = nested;
|
|
392
|
-
return err;
|
|
393
|
-
})(),
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
name: 'HttpException with complex response object',
|
|
397
|
-
value: new HttpException(
|
|
398
|
-
{
|
|
399
|
-
nested: {
|
|
400
|
-
deep: {
|
|
401
|
-
message: 'buried message',
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
circular: {},
|
|
405
|
-
},
|
|
406
|
-
500,
|
|
407
|
-
{ cause: new Error('cause') },
|
|
408
|
-
),
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
name: 'HttpException with array response',
|
|
412
|
-
value: new HttpException(['error1', 'error2'], 400),
|
|
413
|
-
},
|
|
414
|
-
{
|
|
415
|
-
name: 'custom error extending Error with broken inheritance',
|
|
416
|
-
value: (() => {
|
|
417
|
-
function CustomError(this: any, message: string) {
|
|
418
|
-
this.message = message;
|
|
419
|
-
// Not calling Error constructor properly
|
|
420
|
-
}
|
|
421
|
-
CustomError.prototype = Object.create(Error.prototype);
|
|
422
|
-
return new (CustomError as any)('broken inheritance');
|
|
423
|
-
})(),
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
name: 'error with non-enumerable properties',
|
|
427
|
-
value: (() => {
|
|
428
|
-
const err = new Error('hidden props');
|
|
429
|
-
Object.defineProperty(err, 'hiddenCause', {
|
|
430
|
-
value: new Error('hidden cause'),
|
|
431
|
-
enumerable: false,
|
|
432
|
-
});
|
|
433
|
-
return err;
|
|
434
|
-
})(),
|
|
435
|
-
},
|
|
436
|
-
{
|
|
437
|
-
name: 'frozen error object',
|
|
438
|
-
value: Object.freeze(new Error('frozen')),
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
name: 'proxy with revoked handler',
|
|
442
|
-
value: (() => {
|
|
443
|
-
const { proxy, revoke } = Proxy.revocable(
|
|
444
|
-
new Error('revoked proxy'),
|
|
445
|
-
{},
|
|
446
|
-
);
|
|
447
|
-
revoke();
|
|
448
|
-
return proxy;
|
|
449
|
-
})(),
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
name: 'circular reference in cause',
|
|
453
|
-
value: (() => {
|
|
454
|
-
const err: any = new Error('circular cause');
|
|
455
|
-
err.cause = new Error('cause error');
|
|
456
|
-
err.cause.parentError = err;
|
|
457
|
-
return err;
|
|
458
|
-
})(),
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
name: 'fake HttpException with getResponse returning bad value',
|
|
462
|
-
value: Object.assign(new Error('test'), {
|
|
463
|
-
getStatus: () => 500,
|
|
464
|
-
getResponse: () => ({
|
|
465
|
-
toString: () => {
|
|
466
|
-
throw new Error('toString exploded');
|
|
467
|
-
},
|
|
468
|
-
}),
|
|
469
|
-
}),
|
|
470
|
-
},
|
|
471
|
-
{
|
|
472
|
-
name: 'Error with getter that throws on message',
|
|
473
|
-
value: Object.defineProperty(new Error(), 'message', {
|
|
474
|
-
get: () => {
|
|
475
|
-
throw new Error('message getter exploded');
|
|
476
|
-
},
|
|
477
|
-
}),
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
name: 'Error with getter that throws on stack',
|
|
481
|
-
value: Object.defineProperty(new Error('test'), 'stack', {
|
|
482
|
-
get: () => {
|
|
483
|
-
throw new Error('stack getter exploded');
|
|
484
|
-
},
|
|
485
|
-
}),
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
name: 'Error with non string name',
|
|
489
|
-
value: { name: 123 } as unknown as Error,
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
name: 'Error with non string message',
|
|
493
|
-
value: { message: 123 } as unknown as Error,
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
name: 'Error with string cause',
|
|
497
|
-
value: { cause: 'test' } as unknown as Error,
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
name: 'Error with array cause',
|
|
501
|
-
value: { cause: ['test'] } as unknown as Error,
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
name: 'Error with error throwing cause key',
|
|
505
|
-
value: {
|
|
506
|
-
cause: Object.defineProperty({ test: 'test', boom: 'boom' }, 'boom', {
|
|
507
|
-
get: () => {
|
|
508
|
-
throw new Error('cause getter exploded');
|
|
509
|
-
},
|
|
510
|
-
}),
|
|
511
|
-
} as unknown as Error,
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
name: 'Error with getter that throws on name',
|
|
515
|
-
value: Object.defineProperty(new Error('test'), 'name', {
|
|
516
|
-
get: () => {
|
|
517
|
-
throw new Error('name getter exploded');
|
|
518
|
-
},
|
|
519
|
-
}),
|
|
520
|
-
},
|
|
521
|
-
])('should safely convert $name to a DefaultError', ({ value }) => {
|
|
522
|
-
const defaultError = errorToDefaultError(value);
|
|
523
|
-
expect(defaultError).toBeInstanceOf(DefaultError);
|
|
524
|
-
expect(() => JSON.stringify(defaultError)).not.toThrow();
|
|
525
|
-
expect(defaultError.name).toBeDefined();
|
|
526
|
-
expect(defaultError.message).toBeDefined();
|
|
527
|
-
});
|
|
528
|
-
});
|
|
529
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { getStatusCodeFromError } from '../error.helper.js';
|
|
3
|
-
import { BadRequestException, HttpStatus } from '@nestjs/common';
|
|
4
|
-
import { BadRequestError } from '../error.class.js';
|
|
5
|
-
|
|
6
|
-
describe('ErrorHelper', () => {
|
|
7
|
-
it('should return the correct status code', () => {
|
|
8
|
-
expect(getStatusCodeFromError(BadRequestError)).toBe(
|
|
9
|
-
HttpStatus.BAD_REQUEST,
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
expect(getStatusCodeFromError(new BadRequestError())).toBe(
|
|
13
|
-
HttpStatus.BAD_REQUEST,
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
expect(getStatusCodeFromError(new Error())).toBe(null);
|
|
17
|
-
expect(getStatusCodeFromError(Error)).toBe(null);
|
|
18
|
-
|
|
19
|
-
expect(getStatusCodeFromError(BadRequestException)).toBe(
|
|
20
|
-
HttpStatus.BAD_REQUEST,
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
expect,
|
|
3
|
-
jest,
|
|
4
|
-
describe,
|
|
5
|
-
it,
|
|
6
|
-
beforeEach,
|
|
7
|
-
beforeAll,
|
|
8
|
-
afterAll,
|
|
9
|
-
afterEach,
|
|
10
|
-
} from '@jest/globals';
|
|
11
|
-
import { ErrorsEnum, ExceptionContextEnum } from '@node-yalc/errors/error.enum.js';
|
|
12
|
-
|
|
13
|
-
describe('errors enum test', () => {
|
|
14
|
-
it('ErrorsEnum should have all the values', () => {
|
|
15
|
-
expect(Object.keys(ErrorsEnum)).toEqual(
|
|
16
|
-
expect.arrayContaining([
|
|
17
|
-
'BAD_LOGIN',
|
|
18
|
-
'UNAUTHORIZED',
|
|
19
|
-
'FORBIDDEN_RESOURCE',
|
|
20
|
-
'INVALID_VALUE',
|
|
21
|
-
]),
|
|
22
|
-
);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('ExceptionContextEnum have all the values', () => {
|
|
26
|
-
expect(Object.keys(ExceptionContextEnum)).toEqual([
|
|
27
|
-
'DATABASE',
|
|
28
|
-
'HTTP',
|
|
29
|
-
'SYSTEM',
|
|
30
|
-
]);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { HttpStatusCodes } from '@node-yalc/utils/http.helper.js';
|
|
2
|
-
import { httpStatusCodeToErrors } from '../http-status-code-to-errors.js';
|
|
3
|
-
import {
|
|
4
|
-
BadRequestError,
|
|
5
|
-
GatewayTimeoutError,
|
|
6
|
-
NotFoundError,
|
|
7
|
-
} from '../error.class.js';
|
|
8
|
-
import { describe, expect, it } from '@jest/globals';
|
|
9
|
-
|
|
10
|
-
describe('should test ', () => {
|
|
11
|
-
it('should return not found error when given code 404', () => {
|
|
12
|
-
const httpCode: HttpStatusCodes = 404;
|
|
13
|
-
const result = httpStatusCodeToErrors[httpCode];
|
|
14
|
-
expect(result).toBe(NotFoundError);
|
|
15
|
-
});
|
|
16
|
-
it('should return bad request error when given code 400', () => {
|
|
17
|
-
const httpCode: HttpStatusCodes = 400;
|
|
18
|
-
const result = httpStatusCodeToErrors[httpCode];
|
|
19
|
-
expect(result).toBe(BadRequestError);
|
|
20
|
-
});
|
|
21
|
-
it('should return gateway timeout error when given code 504', () => {
|
|
22
|
-
const httpCode: HttpStatusCodes = 504;
|
|
23
|
-
const result = httpStatusCodeToErrors[httpCode];
|
|
24
|
-
expect(result).toBe(GatewayTimeoutError);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
expect,
|
|
3
|
-
jest,
|
|
4
|
-
describe,
|
|
5
|
-
it,
|
|
6
|
-
beforeEach,
|
|
7
|
-
beforeAll,
|
|
8
|
-
afterAll,
|
|
9
|
-
afterEach,
|
|
10
|
-
} from '@jest/globals';
|
|
11
|
-
import { BadRequestError, InputValidationError } from '../error.class.js';
|
|
12
|
-
import { ErrorsEnum } from '@node-yalc/errors/error.enum.js';
|
|
13
|
-
|
|
14
|
-
describe('InputValidationError', () => {
|
|
15
|
-
it('should have internal message without the custom message', () => {
|
|
16
|
-
const customError = new InputValidationError();
|
|
17
|
-
expect(customError.internalMessage).toEqual('Invalid value');
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should set the custom message', () => {
|
|
21
|
-
const customMessage = 'INVALID_INPUT_MESSAGE';
|
|
22
|
-
const customError = new BadRequestError(customMessage);
|
|
23
|
-
expect(customError.internalMessage).toEqual(
|
|
24
|
-
`${ErrorsEnum.BAD_REQUEST}: ${customMessage}`,
|
|
25
|
-
);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { expect, describe, it } from '@jest/globals';
|
|
2
|
-
import { ErrorsEnum } from '@node-yalc/errors/error.enum.js';
|
|
3
|
-
import { LoginError } from '../index.js';
|
|
4
|
-
|
|
5
|
-
describe('Login error', () => {
|
|
6
|
-
const error = new LoginError();
|
|
7
|
-
|
|
8
|
-
it('should be defined', () => {
|
|
9
|
-
expect(error).toBeDefined();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('should have the correct message', () => {
|
|
13
|
-
expect(error.getInternalMessage()).toEqual(ErrorsEnum.BAD_LOGIN);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should set the custom message', () => {
|
|
17
|
-
const customMessage = 'Something catastrophic happened!';
|
|
18
|
-
const customError = new LoginError(customMessage);
|
|
19
|
-
expect(customError.getInternalMessage()).toEqual(
|
|
20
|
-
`${ErrorsEnum.BAD_LOGIN}: ${customMessage}`,
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
});
|