@nest-yalc-2/errors 1.3.4 → 2.1.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/package.json +5 -5
- package/src/__tests__/database-exception.filter.spec.ts +1 -1
- package/src/__tests__/default.error.spec.ts +1 -1
- package/src/__tests__/errors.enum.spec.ts +1 -1
- package/src/__tests__/http-exception.filter.spec.ts +54 -1
- package/src/__tests__/http-status-code-to-errors.spec.ts +1 -1
- package/src/__tests__/input-validation.error.spec.ts +1 -1
- package/src/__tests__/login.error.spec.ts +1 -1
- package/src/__tests__/system-exception.filter.spec.ts +1 -1
- package/src/__tests__/verification.error.spec.ts +1 -1
- package/src/filters/database-exception.filter.d.ts +2 -1
- package/src/filters/database-exception.filter.js +7 -48
- package/src/filters/database-exception.filter.js.map +1 -1
- package/src/filters/database-exception.filter.ts +4 -2
- package/src/filters/http-exception.filter.d.ts +4 -3
- package/src/filters/http-exception.filter.js +6 -47
- package/src/filters/http-exception.filter.js.map +1 -1
- package/src/filters/http-exception.filter.ts +4 -3
- package/src/filters/system-exception.filter.js +5 -13
- package/src/filters/system-exception.filter.js.map +1 -1
- package/src/filters/system-exception.filter.ts +1 -1
- package/src/filters/validation-exception.filter.d.ts +2 -2
- package/src/filters/validation-exception.filter.js +4 -45
- package/src/filters/validation-exception.filter.js.map +1 -1
- package/src/filters/validation-exception.filter.ts +3 -1
- package/src/index.d.ts +5 -4
- package/src/index.js +6 -18
- package/src/index.js.map +1 -1
- package/src/index.ts +5 -4
- package/src/default.error.d.ts +0 -93
- package/src/default.error.js +0 -266
- package/src/default.error.js.map +0 -1
- package/src/default.error.ts +0 -640
- package/src/error.class.d.ts +0 -103
- package/src/error.class.js +0 -170
- package/src/error.class.js.map +0 -1
- package/src/error.class.ts +0 -319
- package/src/error.enum.d.ts +0 -29
- package/src/error.enum.js +0 -41
- package/src/error.enum.js.map +0 -1
- package/src/error.enum.ts +0 -45
- package/src/error.helper.d.ts +0 -2
- package/src/error.helper.js +0 -20
- package/src/error.helper.js.map +0 -1
- package/src/error.helper.ts +0 -34
- package/src/http-status-code-to-errors.d.ts +0 -4
- package/src/http-status-code-to-errors.js +0 -24
- package/src/http-status-code-to-errors.js.map +0 -1
- package/src/http-status-code-to-errors.ts +0 -41
- package/src/result.error.d.ts +0 -4
- package/src/result.error.js +0 -24
- package/src/result.error.js.map +0 -1
- package/src/result.error.ts +0 -25
package/src/default.error.ts
DELETED
|
@@ -1,640 +0,0 @@
|
|
|
1
|
-
import { getLogLevelByStatus } from '@nest-yalc-2/event-manager/event.helper.js';
|
|
2
|
-
import { getYalcGlobalEventEmitter } from '@nest-yalc-2/event-manager/global-emitter.js';
|
|
3
|
-
import type { ImprovedLoggerService } from '@nest-yalc-2/logger/logger-abstract.service.js';
|
|
4
|
-
import { AppLoggerFactory } from '@nest-yalc-2/logger/logger.factory.js';
|
|
5
|
-
import { maskDataInObject } from '@nest-yalc-2/logger/logger.helper.js';
|
|
6
|
-
import { ClassType, Mixin } from '@nest-yalc-2/types/globals.d.js';
|
|
7
|
-
import { getHttpStatusDescription } from '@nest-yalc-2/utils/http.helper.js';
|
|
8
|
-
import {
|
|
9
|
-
HttpException,
|
|
10
|
-
HttpExceptionOptions,
|
|
11
|
-
HttpStatus,
|
|
12
|
-
LogLevel,
|
|
13
|
-
} from '@nestjs/common';
|
|
14
|
-
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
15
|
-
import { getHttpStatusNameByCode } from './error.enum.js';
|
|
16
|
-
import { deepMergeWithoutArrayConcat } from '@nest-yalc-2/utils/object.helper.js';
|
|
17
|
-
import { isClass } from '@nest-yalc-2/utils/class.helper.js';
|
|
18
|
-
|
|
19
|
-
export const ON_DEFAULT_ERROR_EVENT = 'onDefaultError';
|
|
20
|
-
|
|
21
|
-
export interface ISharedErrorProperties {
|
|
22
|
-
/**
|
|
23
|
-
* The data that will be used internally. It can contain sensitive data.
|
|
24
|
-
*/
|
|
25
|
-
data?: any;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Configuration for alarms and event handling
|
|
29
|
-
*/
|
|
30
|
-
config?: any;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* The message that will be used internally. It can contain sensitive data.
|
|
34
|
-
*/
|
|
35
|
-
internalMessage?: string;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Human readable description of the error code
|
|
39
|
-
*/
|
|
40
|
-
description?: string;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* When the event options are specified, this will contain the name of the event
|
|
44
|
-
* that will be emitted within the DefaultError class.
|
|
45
|
-
*/
|
|
46
|
-
eventName?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface IHttpExceptionArguments {
|
|
50
|
-
/**
|
|
51
|
-
* The response that can be sent to the client. It can be a string or an object (including an error object)
|
|
52
|
-
* It must not contain sensitive data.
|
|
53
|
-
*/
|
|
54
|
-
response?: Partial<IBetterResponseInterface>;
|
|
55
|
-
/**
|
|
56
|
-
* Http status code or a custom error code
|
|
57
|
-
*/
|
|
58
|
-
errorCode?: HttpStatus | number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* The arguments used by the NestJS classes that extend the HttpException class.
|
|
63
|
-
*/
|
|
64
|
-
export interface IHttpExceptionParentArguments extends Omit<
|
|
65
|
-
IHttpExceptionArguments,
|
|
66
|
-
'errorCode'
|
|
67
|
-
> {}
|
|
68
|
-
|
|
69
|
-
export interface IErrorPayload extends ISharedErrorProperties {
|
|
70
|
-
/**
|
|
71
|
-
* The response that can be sent to the client. It can be a string or an object (including an error object)
|
|
72
|
-
* It must not contain sensitive data.
|
|
73
|
-
*/
|
|
74
|
-
response?: Partial<IBetterResponseInterface>;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* The original cause of the error.
|
|
78
|
-
*/
|
|
79
|
-
cause?: IFormattedCause;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* When the error is specified, it includes the error name
|
|
83
|
-
*/
|
|
84
|
-
errorName?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface IErrorEventPayload extends IErrorPayload {
|
|
88
|
-
/**
|
|
89
|
-
* This is the message used for the response object. It can be sent to the client
|
|
90
|
-
*/
|
|
91
|
-
message?: string;
|
|
92
|
-
|
|
93
|
-
stack?: string;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export interface ILogErrorPayload extends Omit<
|
|
97
|
-
IErrorEventPayload,
|
|
98
|
-
keyof IHttpExceptionArguments
|
|
99
|
-
> {
|
|
100
|
-
[key: string]: any;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
type loggerOptionType =
|
|
104
|
-
{ instance?: ImprovedLoggerService; level?: LogLevel } | false;
|
|
105
|
-
|
|
106
|
-
export interface IAbstractDefaultError
|
|
107
|
-
extends
|
|
108
|
-
Omit<HttpException, 'cause' | 'message'>,
|
|
109
|
-
Omit<IErrorEventPayload, 'response'> {
|
|
110
|
-
logger?: loggerOptionType;
|
|
111
|
-
eventEmitter?: EventEmitter2;
|
|
112
|
-
getResponse(): IBetterResponseInterface;
|
|
113
|
-
getInternalMessage(): string | undefined;
|
|
114
|
-
getDescription(): string | undefined;
|
|
115
|
-
/**
|
|
116
|
-
* Contains most of the error info that can be used for logging
|
|
117
|
-
* or for event payloads
|
|
118
|
-
*/
|
|
119
|
-
getEventPayload(): IErrorEventPayload;
|
|
120
|
-
setErrorInfo(
|
|
121
|
-
options: IAbstractDefaultErrorOptions & {
|
|
122
|
-
response?: Partial<IBetterResponseInterface>;
|
|
123
|
-
},
|
|
124
|
-
): void;
|
|
125
|
-
mergeErrorInfo(
|
|
126
|
-
info: IAbstractDefaultErrorOptions & {
|
|
127
|
-
response?: Partial<IBetterResponseInterface>;
|
|
128
|
-
cause?: Error;
|
|
129
|
-
},
|
|
130
|
-
): void;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface IAbstractDefaultErrorConstructor<
|
|
134
|
-
TErrorClass extends ClassType<HttpException> = ClassType<HttpException>,
|
|
135
|
-
> {
|
|
136
|
-
new (
|
|
137
|
-
options: IAbstractDefaultErrorOptions,
|
|
138
|
-
...args: ConstructorParameters<TErrorClass>
|
|
139
|
-
): IAbstractDefaultError;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export interface IAbstractDefaultErrorOptions extends ISharedErrorProperties {
|
|
143
|
-
/**
|
|
144
|
-
* This is the list of keys that will be masked in the data object.
|
|
145
|
-
*/
|
|
146
|
-
masks?: string[];
|
|
147
|
-
/**
|
|
148
|
-
* This allow to log the error at the same time it is thrown.
|
|
149
|
-
* If set to true, will use the default logger.
|
|
150
|
-
*/
|
|
151
|
-
logger?: loggerOptionType | boolean;
|
|
152
|
-
/**
|
|
153
|
-
* This allow to emit an event at the same time it is thrown.
|
|
154
|
-
* If set to true, will use the default event emitter.
|
|
155
|
-
* If set to false, will not emit any event.
|
|
156
|
-
* If set to an EventEmitter2 instance, will use that instance.
|
|
157
|
-
*/
|
|
158
|
-
eventEmitter?: EventEmitter2 | boolean;
|
|
159
|
-
/**
|
|
160
|
-
* Specify an event name that will be used when emitting an event
|
|
161
|
-
* with the eventEmitter when it's not set to false.
|
|
162
|
-
*/
|
|
163
|
-
eventName?: string;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Used to override the stack trace generated by the DefaultError class
|
|
167
|
-
* Useful for the error forwarding or wrapping
|
|
168
|
-
*/
|
|
169
|
-
stack?: string;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export interface IDefaultErrorBaseOptions
|
|
173
|
-
extends
|
|
174
|
-
Omit<IAbstractDefaultErrorOptions, 'internalMessage'>,
|
|
175
|
-
HttpExceptionOptions,
|
|
176
|
-
IHttpExceptionParentArguments {}
|
|
177
|
-
|
|
178
|
-
export interface IDefaultErrorOptions
|
|
179
|
-
extends
|
|
180
|
-
Omit<IAbstractDefaultErrorOptions, 'internalMessage'>,
|
|
181
|
-
HttpExceptionOptions,
|
|
182
|
-
IHttpExceptionArguments {}
|
|
183
|
-
|
|
184
|
-
export interface IBetterResponseInterface {
|
|
185
|
-
/**
|
|
186
|
-
* This is the error name (ex: 'Bad Request' or custom error name)
|
|
187
|
-
*/
|
|
188
|
-
error?: string;
|
|
189
|
-
/**
|
|
190
|
-
* This is the error code (ex: 400 or custom error code)
|
|
191
|
-
*/
|
|
192
|
-
statusCode: number;
|
|
193
|
-
/**
|
|
194
|
-
* Human readable description of the status code. Can be automatically generated from the statusCode or set manually.
|
|
195
|
-
*/
|
|
196
|
-
statusCodeDescription: string;
|
|
197
|
-
/**
|
|
198
|
-
* The message can be set manually or automatically generated from the error name.
|
|
199
|
-
* It should describe what happened.
|
|
200
|
-
* Note: the same statusCode can be used for different errors,
|
|
201
|
-
* so the message should be different while the description should remain the same for each statusCode.
|
|
202
|
-
*/
|
|
203
|
-
message: string;
|
|
204
|
-
/**
|
|
205
|
-
* Other properties that can be added dynamically to the response object.
|
|
206
|
-
*/
|
|
207
|
-
[key: string]: any;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* This is a convenience function to create a new DefaultError class instance that extends the provided base class.
|
|
212
|
-
* @param base
|
|
213
|
-
* @param options
|
|
214
|
-
* @param args
|
|
215
|
-
* @returns
|
|
216
|
-
*/
|
|
217
|
-
export const newDefaultError = <
|
|
218
|
-
T extends ClassType<HttpException> = typeof HttpException,
|
|
219
|
-
>(
|
|
220
|
-
base: T,
|
|
221
|
-
options: IAbstractDefaultErrorOptions,
|
|
222
|
-
...args: ConstructorParameters<T>
|
|
223
|
-
) => {
|
|
224
|
-
return new (DefaultErrorMixin(base))(options, ...args);
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
interface IFormattedCause {
|
|
228
|
-
message?: string;
|
|
229
|
-
stack?: string;
|
|
230
|
-
parentCause?: IFormattedCause;
|
|
231
|
-
[key: string]: any;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export function formatCause(error?: any): IFormattedCause | undefined {
|
|
235
|
-
if (!error) {
|
|
236
|
-
return undefined;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
...error,
|
|
241
|
-
message: error.message ?? error.toString(),
|
|
242
|
-
stack: error.stack,
|
|
243
|
-
parentCause: error.cause ? formatCause(error.cause) : undefined,
|
|
244
|
-
cause: undefined,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export const DefaultErrorMixin = <
|
|
249
|
-
T extends ClassType<HttpException> = ClassType<HttpException>,
|
|
250
|
-
>(
|
|
251
|
-
base?: T,
|
|
252
|
-
): IAbstractDefaultErrorConstructor<T> => {
|
|
253
|
-
const BaseClass: ClassType<HttpException> = base ?? HttpException;
|
|
254
|
-
|
|
255
|
-
class _AbstractDefaultError
|
|
256
|
-
extends BaseClass
|
|
257
|
-
implements IAbstractDefaultError
|
|
258
|
-
{
|
|
259
|
-
static defaultStatusCode = HttpStatus.INTERNAL_SERVER_ERROR;
|
|
260
|
-
|
|
261
|
-
data?: any;
|
|
262
|
-
description?: string;
|
|
263
|
-
internalMessage?: string;
|
|
264
|
-
eventName?: string;
|
|
265
|
-
override cause: IFormattedCause | undefined;
|
|
266
|
-
resolvedStack?: string;
|
|
267
|
-
|
|
268
|
-
__DefaultErrorMixin = Object.freeze(true);
|
|
269
|
-
|
|
270
|
-
protected eventPayload!: IErrorEventPayload;
|
|
271
|
-
protected betterResponse!: IBetterResponseInterface;
|
|
272
|
-
public readonly logger?: Required<loggerOptionType>;
|
|
273
|
-
public readonly eventEmitter?: EventEmitter2;
|
|
274
|
-
|
|
275
|
-
constructor(
|
|
276
|
-
options: IAbstractDefaultErrorOptions,
|
|
277
|
-
...args: ConstructorParameters<T>
|
|
278
|
-
) {
|
|
279
|
-
super(...args);
|
|
280
|
-
|
|
281
|
-
const message = options.internalMessage ?? this.message;
|
|
282
|
-
|
|
283
|
-
this.setErrorInfo(options);
|
|
284
|
-
|
|
285
|
-
if (options.logger) {
|
|
286
|
-
const { instance, level } =
|
|
287
|
-
options.logger !== true
|
|
288
|
-
? options.logger
|
|
289
|
-
: { instance: undefined, level: undefined };
|
|
290
|
-
|
|
291
|
-
this.logger = {
|
|
292
|
-
instance: instance ?? AppLoggerFactory('DefaultError'),
|
|
293
|
-
level: level ?? getLogLevelByStatus(this.getStatus()),
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
if (this.logger.level === 'error') {
|
|
297
|
-
this.logger.instance.error(message, this.resolvedStack, {
|
|
298
|
-
data: this.eventPayload,
|
|
299
|
-
stack: this.resolvedStack,
|
|
300
|
-
});
|
|
301
|
-
} else {
|
|
302
|
-
this.logger.instance?.[this.logger.level]?.(message, {
|
|
303
|
-
data: this.eventPayload,
|
|
304
|
-
stack: this.resolvedStack,
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const eventEmitter =
|
|
310
|
-
options.eventEmitter === true || options.eventEmitter === undefined
|
|
311
|
-
? getYalcGlobalEventEmitter()
|
|
312
|
-
: options.eventEmitter;
|
|
313
|
-
|
|
314
|
-
if (eventEmitter !== false) {
|
|
315
|
-
this.eventName ??= ON_DEFAULT_ERROR_EVENT;
|
|
316
|
-
this.eventEmitter = eventEmitter;
|
|
317
|
-
this.eventEmitter.emit(this.eventName, {
|
|
318
|
-
...this.eventPayload,
|
|
319
|
-
eventName: this.eventName,
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
setErrorInfo(
|
|
325
|
-
options: IAbstractDefaultErrorOptions & {
|
|
326
|
-
response?: Partial<IBetterResponseInterface>;
|
|
327
|
-
},
|
|
328
|
-
) {
|
|
329
|
-
const stack = options.stack ?? this.stack;
|
|
330
|
-
const errorCode = this.getStatus();
|
|
331
|
-
|
|
332
|
-
this.cause = formatCause(this.cause);
|
|
333
|
-
this.internalMessage = options.internalMessage ?? this.cause?.message;
|
|
334
|
-
this.eventName = options.eventName;
|
|
335
|
-
|
|
336
|
-
this.description =
|
|
337
|
-
options.description ?? getHttpStatusDescription(errorCode);
|
|
338
|
-
|
|
339
|
-
this.betterResponse = _AbstractDefaultError.buildResponse(
|
|
340
|
-
this.message,
|
|
341
|
-
this.description,
|
|
342
|
-
errorCode,
|
|
343
|
-
options?.response ?? super.getResponse(),
|
|
344
|
-
);
|
|
345
|
-
|
|
346
|
-
this.data = options.masks
|
|
347
|
-
? maskDataInObject(options.data, options.masks)
|
|
348
|
-
: options.data;
|
|
349
|
-
|
|
350
|
-
const cause = this.cause;
|
|
351
|
-
|
|
352
|
-
const payload: ILogErrorPayload = {
|
|
353
|
-
data: this.data,
|
|
354
|
-
eventName: this.eventName,
|
|
355
|
-
description: this.description,
|
|
356
|
-
internalMessage: this.internalMessage,
|
|
357
|
-
errorName: this.name,
|
|
358
|
-
...this.betterResponse,
|
|
359
|
-
stack,
|
|
360
|
-
cause,
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
this.resolvedStack = stack;
|
|
364
|
-
this.eventPayload = payload;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Deep merge the error info with the provided info.
|
|
369
|
-
*/
|
|
370
|
-
mergeErrorInfo(
|
|
371
|
-
info: IAbstractDefaultErrorOptions & {
|
|
372
|
-
response?: Partial<IBetterResponseInterface>;
|
|
373
|
-
cause?: Error;
|
|
374
|
-
},
|
|
375
|
-
) {
|
|
376
|
-
const {
|
|
377
|
-
internalMessage,
|
|
378
|
-
description,
|
|
379
|
-
eventName,
|
|
380
|
-
data,
|
|
381
|
-
stack,
|
|
382
|
-
cause,
|
|
383
|
-
response,
|
|
384
|
-
...rest
|
|
385
|
-
} = info;
|
|
386
|
-
|
|
387
|
-
if (internalMessage) this.internalMessage = internalMessage;
|
|
388
|
-
if (description) this.description = description;
|
|
389
|
-
if (eventName) this.eventName = eventName;
|
|
390
|
-
|
|
391
|
-
if (data) this.data = deepMergeWithoutArrayConcat(this.data ?? {}, data);
|
|
392
|
-
|
|
393
|
-
if (stack) this.resolvedStack = stack;
|
|
394
|
-
|
|
395
|
-
if (cause) {
|
|
396
|
-
this.cause = formatCause(cause);
|
|
397
|
-
this.eventPayload.cause = this.cause;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (response) {
|
|
401
|
-
this.betterResponse = {
|
|
402
|
-
...this.betterResponse!,
|
|
403
|
-
..._AbstractDefaultError.buildResponse(
|
|
404
|
-
this.message,
|
|
405
|
-
this.description!,
|
|
406
|
-
this.getStatus(),
|
|
407
|
-
response,
|
|
408
|
-
),
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
this.message = this.betterResponse.message;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
this.eventPayload = {
|
|
415
|
-
...this.eventPayload,
|
|
416
|
-
...rest,
|
|
417
|
-
data: this.data,
|
|
418
|
-
eventName: this.eventName,
|
|
419
|
-
description: this.description,
|
|
420
|
-
internalMessage: this.internalMessage,
|
|
421
|
-
errorName: this.name,
|
|
422
|
-
...this.betterResponse,
|
|
423
|
-
stack: this.resolvedStack,
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
getEventPayload(): IErrorEventPayload {
|
|
428
|
-
return this.eventPayload;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
getInternalMessage(): string | undefined {
|
|
432
|
-
return this.internalMessage;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
getDescription(): string | undefined {
|
|
436
|
-
return this.description;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
getResponse(): IBetterResponseInterface {
|
|
440
|
-
return this.betterResponse;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
toString(): string {
|
|
444
|
-
return `${
|
|
445
|
-
this.internalMessage ?? this.message
|
|
446
|
-
} -\n [INFO: ${JSON.stringify(this.eventPayload, null, 2)}]`;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
static buildResponse(
|
|
450
|
-
message: string,
|
|
451
|
-
codeDescription: string,
|
|
452
|
-
statusCode: number,
|
|
453
|
-
response: string | Record<string, any>,
|
|
454
|
-
): IBetterResponseInterface {
|
|
455
|
-
let responseObj: Record<string, any> = {};
|
|
456
|
-
if (typeof response === 'string' || response instanceof String) {
|
|
457
|
-
message = response as string;
|
|
458
|
-
} else {
|
|
459
|
-
responseObj = response as Record<string, any>;
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* We know that passing a string as the first argument
|
|
463
|
-
* it returns an object with the message, error and the statusCode.
|
|
464
|
-
*/
|
|
465
|
-
const baseBody = HttpException.createBody(
|
|
466
|
-
message,
|
|
467
|
-
getHttpStatusNameByCode(statusCode),
|
|
468
|
-
statusCode,
|
|
469
|
-
) as { message: string; statusCode: number; error?: string };
|
|
470
|
-
|
|
471
|
-
return {
|
|
472
|
-
statusCodeDescription: codeDescription,
|
|
473
|
-
...baseBody,
|
|
474
|
-
message,
|
|
475
|
-
...responseObj,
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return _AbstractDefaultError;
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
export type DefaultErrorMixin = Mixin<typeof DefaultErrorMixin>;
|
|
484
|
-
|
|
485
|
-
export interface IDefaultErrorBaseConstructor<
|
|
486
|
-
T extends ClassType<HttpException> = ClassType<HttpException>,
|
|
487
|
-
> {
|
|
488
|
-
new (
|
|
489
|
-
internalMessage?: string,
|
|
490
|
-
/**
|
|
491
|
-
* These are the DefaultError extended options.
|
|
492
|
-
*/
|
|
493
|
-
options?: Omit<IAbstractDefaultErrorOptions, 'internalMessage'>,
|
|
494
|
-
...args: ConstructorParameters<T>
|
|
495
|
-
): IAbstractDefaultError;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
*
|
|
500
|
-
* Can be used to create new HttpException classes that extend the DefaultError class.
|
|
501
|
-
*
|
|
502
|
-
*/
|
|
503
|
-
export function DefaultErrorBase<
|
|
504
|
-
T extends ClassType<HttpException> = ClassType<HttpException>,
|
|
505
|
-
>(base?: T): IDefaultErrorBaseConstructor<T> {
|
|
506
|
-
return class extends DefaultErrorMixin(base ?? HttpException) {
|
|
507
|
-
static defaultStatusCode = HttpStatus.INTERNAL_SERVER_ERROR;
|
|
508
|
-
constructor(
|
|
509
|
-
internalMessage?: string,
|
|
510
|
-
/**
|
|
511
|
-
* These are the DefaultError extended options.
|
|
512
|
-
*/
|
|
513
|
-
options?: Omit<IAbstractDefaultErrorOptions, 'internalMessage'>,
|
|
514
|
-
...args: ConstructorParameters<T>
|
|
515
|
-
) {
|
|
516
|
-
super({ ...(options ?? {}), internalMessage }, ...args);
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Default error that can be triggered without the base class
|
|
523
|
-
* It extends the HttpException class and the IAbstractDefaultError interface.
|
|
524
|
-
*/
|
|
525
|
-
export class DefaultError extends DefaultErrorBase(HttpException) {
|
|
526
|
-
static defaultStatusCode = HttpStatus.INTERNAL_SERVER_ERROR;
|
|
527
|
-
constructor(
|
|
528
|
-
internalMessage?: string,
|
|
529
|
-
/**
|
|
530
|
-
* These are the DefaultError extended options.
|
|
531
|
-
*/
|
|
532
|
-
options?: IDefaultErrorOptions,
|
|
533
|
-
) {
|
|
534
|
-
const { description, cause, response, errorCode, ...defaultOptions } =
|
|
535
|
-
options ?? {};
|
|
536
|
-
super(
|
|
537
|
-
internalMessage,
|
|
538
|
-
{ ...defaultOptions, description },
|
|
539
|
-
response ?? {},
|
|
540
|
-
errorCode ?? HttpStatus.INTERNAL_SERVER_ERROR,
|
|
541
|
-
{
|
|
542
|
-
description,
|
|
543
|
-
cause,
|
|
544
|
-
},
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
export const errorToDefaultError = (
|
|
550
|
-
error: Error | HttpException | DefaultError,
|
|
551
|
-
options: IDefaultErrorOptions = {},
|
|
552
|
-
) => {
|
|
553
|
-
try {
|
|
554
|
-
if (isDefaultErrorMixin(error)) {
|
|
555
|
-
return error;
|
|
556
|
-
}
|
|
557
|
-
// eslint-disable-next-line no-empty
|
|
558
|
-
} catch (e) {}
|
|
559
|
-
|
|
560
|
-
try {
|
|
561
|
-
if (error instanceof HttpException) {
|
|
562
|
-
// Test if it can be safely stringified
|
|
563
|
-
JSON.stringify(error.cause);
|
|
564
|
-
return new DefaultError(error.message, {
|
|
565
|
-
errorCode: error.getStatus(),
|
|
566
|
-
response: {
|
|
567
|
-
message: error.getResponse().toString(),
|
|
568
|
-
error: error.name,
|
|
569
|
-
statusCode: error.getStatus(),
|
|
570
|
-
statusCodeDescription: getHttpStatusDescription(error.getStatus()),
|
|
571
|
-
},
|
|
572
|
-
stack: error.stack,
|
|
573
|
-
cause: error.cause,
|
|
574
|
-
...options,
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
// eslint-disable-next-line no-empty
|
|
578
|
-
} catch (e) {}
|
|
579
|
-
|
|
580
|
-
let name;
|
|
581
|
-
try {
|
|
582
|
-
name = error.name ?? 'UnknownError';
|
|
583
|
-
if (typeof name !== 'string') {
|
|
584
|
-
name = 'UnknownError';
|
|
585
|
-
}
|
|
586
|
-
} catch (e) {
|
|
587
|
-
name = 'UnknownError';
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
let message;
|
|
591
|
-
try {
|
|
592
|
-
message = error.message ?? 'UnknownError';
|
|
593
|
-
if (typeof message !== 'string') {
|
|
594
|
-
message = 'UnknownError';
|
|
595
|
-
}
|
|
596
|
-
} catch (e) {
|
|
597
|
-
message = 'UnknownError';
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
let stack;
|
|
601
|
-
try {
|
|
602
|
-
// Test if it can be safely stringified
|
|
603
|
-
JSON.stringify(error.stack);
|
|
604
|
-
stack = error.stack;
|
|
605
|
-
// eslint-disable-next-line no-empty
|
|
606
|
-
} catch (e) {}
|
|
607
|
-
|
|
608
|
-
let cause: any;
|
|
609
|
-
try {
|
|
610
|
-
const errorCause = (error as Error & { cause?: unknown }).cause;
|
|
611
|
-
// Test if it can be safely stringified
|
|
612
|
-
JSON.stringify(errorCause);
|
|
613
|
-
cause = errorCause;
|
|
614
|
-
// eslint-disable-next-line no-empty
|
|
615
|
-
} catch (e) {}
|
|
616
|
-
|
|
617
|
-
return new DefaultError(message, {
|
|
618
|
-
stack,
|
|
619
|
-
cause,
|
|
620
|
-
response: {
|
|
621
|
-
error: name,
|
|
622
|
-
},
|
|
623
|
-
...options,
|
|
624
|
-
});
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
export function isDefaultErrorMixin(
|
|
628
|
-
error: any,
|
|
629
|
-
): error is IAbstractDefaultError {
|
|
630
|
-
return (error as any).__DefaultErrorMixin !== undefined;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
export function isDefaultErrorMixinClass(
|
|
634
|
-
error: any,
|
|
635
|
-
): error is typeof DefaultError {
|
|
636
|
-
return (
|
|
637
|
-
isClass(error) &&
|
|
638
|
-
(error as typeof DefaultError).defaultStatusCode !== undefined
|
|
639
|
-
);
|
|
640
|
-
}
|