nestjs-exception-handler 4.1.0 → 4.2.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/dist/index.d.mts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +267 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +270 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PrismaClientKnownRequestError, PrismaClientValidationError, PrismaClientRustPanicError, PrismaClientInitializationError } from '@prisma/client/runtime/library';
|
|
2
|
-
import { HttpException, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
|
|
2
|
+
import { HttpException, ExceptionFilter, ArgumentsHost, DynamicModule } from '@nestjs/common';
|
|
3
3
|
|
|
4
4
|
interface IErrorMessage {
|
|
5
5
|
path: string;
|
|
@@ -24,7 +24,10 @@ interface ExceptionHandlerConfig {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
type PrismaError = PrismaClientKnownRequestError | PrismaClientValidationError | PrismaClientRustPanicError | PrismaClientInitializationError | unknown;
|
|
27
|
-
declare class PrismaExceptionFormatter {
|
|
27
|
+
declare class PrismaExceptionFormatter implements ExceptionFormatter {
|
|
28
|
+
supports(exception: unknown): boolean;
|
|
29
|
+
format(exception: unknown): IErrorMessage[];
|
|
30
|
+
message(_exception: unknown): string;
|
|
28
31
|
formatError(exception: PrismaError): IErrorMessage[];
|
|
29
32
|
private formatPrismaError;
|
|
30
33
|
private formatQueryError;
|
|
@@ -50,7 +53,25 @@ declare class GlobalExceptionFilter implements ExceptionFilter {
|
|
|
50
53
|
catch(exception: unknown, host: ArgumentsHost): void;
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
declare class ExceptionHandlerService {
|
|
57
|
+
private formatters;
|
|
58
|
+
private defaultFormatter;
|
|
59
|
+
constructor();
|
|
60
|
+
registerFormatter(formatter: ExceptionFormatter): void;
|
|
61
|
+
getFormatter(exception: unknown): ExceptionFormatter;
|
|
62
|
+
formatException(exception: unknown): {
|
|
63
|
+
errors: ErrorMessage[];
|
|
64
|
+
message: string;
|
|
65
|
+
};
|
|
66
|
+
formatErrors(exception: unknown): ErrorMessage[];
|
|
67
|
+
getErrorMessage(exception: unknown): string;
|
|
68
|
+
getAllFormatters(): ExceptionFormatter[];
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
declare class ExceptionHandlerModule {
|
|
72
|
+
static forRoot(config?: ExceptionHandlerConfig): DynamicModule;
|
|
73
|
+
static forFeature(config?: ExceptionHandlerConfig): DynamicModule;
|
|
54
74
|
}
|
|
75
|
+
declare function initializeFormatters(service: ExceptionHandlerService): void;
|
|
55
76
|
|
|
56
|
-
export { DtoValidationFormatter, ErrorMessage, ExceptionFormatter, ExceptionHandlerConfig, ExceptionHandlerModule, GlobalExceptionFilter, IErrorMessage, OtherExceptionFormatter, PrismaExceptionFormatter, StandardErrorResponse };
|
|
77
|
+
export { DtoValidationFormatter, ErrorMessage, ExceptionFormatter, ExceptionHandlerConfig, ExceptionHandlerModule, GlobalExceptionFilter, IErrorMessage, OtherExceptionFormatter, PrismaExceptionFormatter, StandardErrorResponse, initializeFormatters };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PrismaClientKnownRequestError, PrismaClientValidationError, PrismaClientRustPanicError, PrismaClientInitializationError } from '@prisma/client/runtime/library';
|
|
2
|
-
import { HttpException, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
|
|
2
|
+
import { HttpException, ExceptionFilter, ArgumentsHost, DynamicModule } from '@nestjs/common';
|
|
3
3
|
|
|
4
4
|
interface IErrorMessage {
|
|
5
5
|
path: string;
|
|
@@ -24,7 +24,10 @@ interface ExceptionHandlerConfig {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
type PrismaError = PrismaClientKnownRequestError | PrismaClientValidationError | PrismaClientRustPanicError | PrismaClientInitializationError | unknown;
|
|
27
|
-
declare class PrismaExceptionFormatter {
|
|
27
|
+
declare class PrismaExceptionFormatter implements ExceptionFormatter {
|
|
28
|
+
supports(exception: unknown): boolean;
|
|
29
|
+
format(exception: unknown): IErrorMessage[];
|
|
30
|
+
message(_exception: unknown): string;
|
|
28
31
|
formatError(exception: PrismaError): IErrorMessage[];
|
|
29
32
|
private formatPrismaError;
|
|
30
33
|
private formatQueryError;
|
|
@@ -50,7 +53,25 @@ declare class GlobalExceptionFilter implements ExceptionFilter {
|
|
|
50
53
|
catch(exception: unknown, host: ArgumentsHost): void;
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
declare class ExceptionHandlerService {
|
|
57
|
+
private formatters;
|
|
58
|
+
private defaultFormatter;
|
|
59
|
+
constructor();
|
|
60
|
+
registerFormatter(formatter: ExceptionFormatter): void;
|
|
61
|
+
getFormatter(exception: unknown): ExceptionFormatter;
|
|
62
|
+
formatException(exception: unknown): {
|
|
63
|
+
errors: ErrorMessage[];
|
|
64
|
+
message: string;
|
|
65
|
+
};
|
|
66
|
+
formatErrors(exception: unknown): ErrorMessage[];
|
|
67
|
+
getErrorMessage(exception: unknown): string;
|
|
68
|
+
getAllFormatters(): ExceptionFormatter[];
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
declare class ExceptionHandlerModule {
|
|
72
|
+
static forRoot(config?: ExceptionHandlerConfig): DynamicModule;
|
|
73
|
+
static forFeature(config?: ExceptionHandlerConfig): DynamicModule;
|
|
54
74
|
}
|
|
75
|
+
declare function initializeFormatters(service: ExceptionHandlerService): void;
|
|
55
76
|
|
|
56
|
-
export { DtoValidationFormatter, ErrorMessage, ExceptionFormatter, ExceptionHandlerConfig, ExceptionHandlerModule, GlobalExceptionFilter, IErrorMessage, OtherExceptionFormatter, PrismaExceptionFormatter, StandardErrorResponse };
|
|
77
|
+
export { DtoValidationFormatter, ErrorMessage, ExceptionFormatter, ExceptionHandlerConfig, ExceptionHandlerModule, GlobalExceptionFilter, IErrorMessage, OtherExceptionFormatter, PrismaExceptionFormatter, StandardErrorResponse, initializeFormatters };
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,8 @@ __export(src_exports, {
|
|
|
33
33
|
ExceptionHandlerModule: () => ExceptionHandlerModule,
|
|
34
34
|
GlobalExceptionFilter: () => GlobalExceptionFilter,
|
|
35
35
|
OtherExceptionFormatter: () => OtherExceptionFormatter,
|
|
36
|
-
PrismaExceptionFormatter: () => PrismaExceptionFormatter
|
|
36
|
+
PrismaExceptionFormatter: () => PrismaExceptionFormatter,
|
|
37
|
+
initializeFormatters: () => initializeFormatters
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(src_exports);
|
|
39
40
|
|
|
@@ -41,6 +42,15 @@ module.exports = __toCommonJS(src_exports);
|
|
|
41
42
|
var import_common = require("@nestjs/common");
|
|
42
43
|
var import_library = require("@prisma/client/runtime/library");
|
|
43
44
|
var PrismaExceptionFormatter = class {
|
|
45
|
+
supports(exception) {
|
|
46
|
+
return exception instanceof import_library.PrismaClientKnownRequestError || exception instanceof import_library.PrismaClientValidationError || exception instanceof import_library.PrismaClientRustPanicError || exception instanceof import_library.PrismaClientInitializationError;
|
|
47
|
+
}
|
|
48
|
+
format(exception) {
|
|
49
|
+
return this.formatError(exception);
|
|
50
|
+
}
|
|
51
|
+
message(_exception) {
|
|
52
|
+
return "Database error";
|
|
53
|
+
}
|
|
44
54
|
formatError(exception) {
|
|
45
55
|
if (exception instanceof import_library.PrismaClientKnownRequestError) {
|
|
46
56
|
return this.formatPrismaError(exception);
|
|
@@ -247,27 +257,272 @@ GlobalExceptionFilter = __decorateClass([
|
|
|
247
257
|
(0, import_common4.Catch)()
|
|
248
258
|
], GlobalExceptionFilter);
|
|
249
259
|
|
|
250
|
-
// src/exception-handler.module.ts
|
|
260
|
+
// src/module/exception-handler.module.ts
|
|
261
|
+
var import_common8 = require("@nestjs/common");
|
|
262
|
+
|
|
263
|
+
// src/services/exception-handler.service.ts
|
|
251
264
|
var import_common5 = require("@nestjs/common");
|
|
265
|
+
|
|
266
|
+
// src/constants/default-messages.ts
|
|
267
|
+
var DEFAULT_PATH = "unknown";
|
|
268
|
+
|
|
269
|
+
// src/formatters/unknown-exception.formatter.ts
|
|
270
|
+
var UnknownExceptionFormatter = class {
|
|
271
|
+
supports(_exception) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
format(_exception) {
|
|
275
|
+
return [
|
|
276
|
+
{
|
|
277
|
+
path: DEFAULT_PATH,
|
|
278
|
+
message: "Internal server error"
|
|
279
|
+
}
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
message(_exception) {
|
|
283
|
+
return "Internal server error";
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// src/services/exception-handler.service.ts
|
|
288
|
+
var ExceptionHandlerService = class {
|
|
289
|
+
constructor() {
|
|
290
|
+
this.formatters = [];
|
|
291
|
+
this.defaultFormatter = new UnknownExceptionFormatter();
|
|
292
|
+
}
|
|
293
|
+
registerFormatter(formatter) {
|
|
294
|
+
this.formatters.push(formatter);
|
|
295
|
+
}
|
|
296
|
+
getFormatter(exception) {
|
|
297
|
+
for (const formatter of this.formatters) {
|
|
298
|
+
if (formatter.supports(exception)) {
|
|
299
|
+
return formatter;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return this.defaultFormatter;
|
|
303
|
+
}
|
|
304
|
+
formatException(exception) {
|
|
305
|
+
const formatter = this.getFormatter(exception);
|
|
306
|
+
const errors = formatter.format(exception);
|
|
307
|
+
const message = formatter.message(exception);
|
|
308
|
+
return { errors, message };
|
|
309
|
+
}
|
|
310
|
+
formatErrors(exception) {
|
|
311
|
+
const formatter = this.getFormatter(exception);
|
|
312
|
+
return formatter.format(exception);
|
|
313
|
+
}
|
|
314
|
+
getErrorMessage(exception) {
|
|
315
|
+
const formatter = this.getFormatter(exception);
|
|
316
|
+
return formatter.message(exception);
|
|
317
|
+
}
|
|
318
|
+
getAllFormatters() {
|
|
319
|
+
return [...this.formatters];
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
ExceptionHandlerService = __decorateClass([
|
|
323
|
+
(0, import_common5.Injectable)()
|
|
324
|
+
], ExceptionHandlerService);
|
|
325
|
+
|
|
326
|
+
// src/filter/global-exception.filter.ts
|
|
327
|
+
var import_common6 = require("@nestjs/common");
|
|
328
|
+
var GlobalExceptionFilter2 = class {
|
|
329
|
+
constructor(exceptionHandlerService, config) {
|
|
330
|
+
this.exceptionHandlerService = exceptionHandlerService;
|
|
331
|
+
this.logger = new import_common6.Logger(GlobalExceptionFilter2.name);
|
|
332
|
+
this.config = config || { enableLogging: true, hideStackTrace: false };
|
|
333
|
+
}
|
|
334
|
+
catch(exception, host) {
|
|
335
|
+
const ctx = host.switchToHttp();
|
|
336
|
+
const response = ctx.getResponse();
|
|
337
|
+
const request = ctx.getRequest();
|
|
338
|
+
const { errors, message } = this.exceptionHandlerService.formatException(exception);
|
|
339
|
+
const status = this.getStatusCode(exception);
|
|
340
|
+
const errorResponse = {
|
|
341
|
+
success: false,
|
|
342
|
+
message,
|
|
343
|
+
errorMessages: errors
|
|
344
|
+
};
|
|
345
|
+
if (this.config.enableLogging) {
|
|
346
|
+
this.logError(request, status, errors, exception);
|
|
347
|
+
}
|
|
348
|
+
response.status(status).json(errorResponse);
|
|
349
|
+
}
|
|
350
|
+
getStatusCode(exception) {
|
|
351
|
+
if (exception instanceof import_common6.HttpException) {
|
|
352
|
+
return exception.getStatus();
|
|
353
|
+
}
|
|
354
|
+
return import_common6.HttpStatus.INTERNAL_SERVER_ERROR;
|
|
355
|
+
}
|
|
356
|
+
logError(request, status, errorMessages, exception) {
|
|
357
|
+
const method = request.method;
|
|
358
|
+
const url = request.url;
|
|
359
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
360
|
+
const logData = {
|
|
361
|
+
timestamp,
|
|
362
|
+
method,
|
|
363
|
+
url,
|
|
364
|
+
status,
|
|
365
|
+
errorMessages,
|
|
366
|
+
stack: this.config.hideStackTrace ? void 0 : exception?.stack
|
|
367
|
+
};
|
|
368
|
+
this.logger.error(`${method} ${url} - ${status}`, JSON.stringify(logData));
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
GlobalExceptionFilter2 = __decorateClass([
|
|
372
|
+
(0, import_common6.Catch)()
|
|
373
|
+
], GlobalExceptionFilter2);
|
|
374
|
+
|
|
375
|
+
// src/formatters/dto-exception.formatter.ts
|
|
376
|
+
var DtoExceptionFormatter = class {
|
|
377
|
+
supports(exception) {
|
|
378
|
+
if (!exception || typeof exception !== "object") {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
const error = exception;
|
|
382
|
+
return Array.isArray(error.validationErrors) || Array.isArray(error.children) && error.constraints !== void 0;
|
|
383
|
+
}
|
|
384
|
+
format(exception) {
|
|
385
|
+
const error = exception;
|
|
386
|
+
const validationErrors = error.validationErrors;
|
|
387
|
+
const children = error.children;
|
|
388
|
+
if (validationErrors) {
|
|
389
|
+
return this.formatValidationErrors(validationErrors);
|
|
390
|
+
}
|
|
391
|
+
if (children) {
|
|
392
|
+
return this.formatChildrenErrors(children);
|
|
393
|
+
}
|
|
394
|
+
return [{ path: "unknown", message: "Validation failed" }];
|
|
395
|
+
}
|
|
396
|
+
message(exception) {
|
|
397
|
+
const error = exception;
|
|
398
|
+
const validationErrors = error.validationErrors;
|
|
399
|
+
const children = error.children;
|
|
400
|
+
if (validationErrors && validationErrors.length > 0) {
|
|
401
|
+
const firstError = validationErrors[0];
|
|
402
|
+
const constraints = firstError.constraints;
|
|
403
|
+
if (constraints) {
|
|
404
|
+
return Object.values(constraints)[0];
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (children && children.length > 0) {
|
|
408
|
+
return "Validation failed for nested fields";
|
|
409
|
+
}
|
|
410
|
+
return "Validation failed";
|
|
411
|
+
}
|
|
412
|
+
formatValidationErrors(errors) {
|
|
413
|
+
return errors.flatMap((error) => {
|
|
414
|
+
const constraints = error.constraints;
|
|
415
|
+
if (constraints) {
|
|
416
|
+
return Object.entries(constraints).map(([, value]) => ({
|
|
417
|
+
path: error.property,
|
|
418
|
+
message: value
|
|
419
|
+
}));
|
|
420
|
+
}
|
|
421
|
+
return [];
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
formatChildrenErrors(children) {
|
|
425
|
+
return children.flatMap((child) => {
|
|
426
|
+
const constraints = child.constraints;
|
|
427
|
+
if (constraints) {
|
|
428
|
+
return Object.entries(constraints).map(([, value]) => ({
|
|
429
|
+
path: child.property,
|
|
430
|
+
message: value
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
return [];
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
// src/formatters/http-exception.formatter.ts
|
|
439
|
+
var import_common7 = require("@nestjs/common");
|
|
440
|
+
var HttpExceptionFormatter = class {
|
|
441
|
+
supports(exception) {
|
|
442
|
+
return exception instanceof import_common7.HttpException;
|
|
443
|
+
}
|
|
444
|
+
format(exception) {
|
|
445
|
+
const httpException = exception;
|
|
446
|
+
const response = httpException.getResponse();
|
|
447
|
+
if (typeof response === "string") {
|
|
448
|
+
return [{ path: "unknown", message: response }];
|
|
449
|
+
}
|
|
450
|
+
if (typeof response === "object" && response !== null) {
|
|
451
|
+
const responseObj = response;
|
|
452
|
+
if (responseObj.message && Array.isArray(responseObj.message)) {
|
|
453
|
+
return responseObj.message.map((msg) => ({
|
|
454
|
+
path: "unknown",
|
|
455
|
+
message: msg
|
|
456
|
+
}));
|
|
457
|
+
}
|
|
458
|
+
if (responseObj.message && typeof responseObj.message === "string") {
|
|
459
|
+
return [{ path: "unknown", message: responseObj.message }];
|
|
460
|
+
}
|
|
461
|
+
if (responseObj.error && typeof responseObj.error === "string") {
|
|
462
|
+
return [{ path: "unknown", message: responseObj.error }];
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return [{ path: "unknown", message: "An error occurred" }];
|
|
466
|
+
}
|
|
467
|
+
message(exception) {
|
|
468
|
+
const httpException = exception;
|
|
469
|
+
const response = httpException.getResponse();
|
|
470
|
+
if (typeof response === "string") {
|
|
471
|
+
return response;
|
|
472
|
+
}
|
|
473
|
+
if (typeof response === "object" && response !== null) {
|
|
474
|
+
const responseObj = response;
|
|
475
|
+
if (responseObj.message && typeof responseObj.message === "string") {
|
|
476
|
+
return responseObj.message;
|
|
477
|
+
}
|
|
478
|
+
if (responseObj.error && typeof responseObj.error === "string") {
|
|
479
|
+
return responseObj.error;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return "An error occurred";
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
// src/module/exception-handler.module.ts
|
|
252
487
|
var ExceptionHandlerModule = class {
|
|
488
|
+
static forRoot(config) {
|
|
489
|
+
const providers = [
|
|
490
|
+
ExceptionHandlerService,
|
|
491
|
+
{
|
|
492
|
+
provide: GlobalExceptionFilter2,
|
|
493
|
+
useFactory: (service) => {
|
|
494
|
+
return new GlobalExceptionFilter2(service, config);
|
|
495
|
+
},
|
|
496
|
+
inject: [ExceptionHandlerService]
|
|
497
|
+
}
|
|
498
|
+
];
|
|
499
|
+
return {
|
|
500
|
+
module: ExceptionHandlerModule,
|
|
501
|
+
providers,
|
|
502
|
+
exports: [ExceptionHandlerService, GlobalExceptionFilter2],
|
|
503
|
+
global: true
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
static forFeature(config) {
|
|
507
|
+
return this.forRoot(config);
|
|
508
|
+
}
|
|
253
509
|
};
|
|
254
510
|
ExceptionHandlerModule = __decorateClass([
|
|
255
|
-
(0,
|
|
256
|
-
providers: [
|
|
257
|
-
GlobalExceptionFilter,
|
|
258
|
-
PrismaExceptionFormatter,
|
|
259
|
-
DtoValidationFormatter,
|
|
260
|
-
OtherExceptionFormatter
|
|
261
|
-
],
|
|
262
|
-
exports: [GlobalExceptionFilter]
|
|
263
|
-
})
|
|
511
|
+
(0, import_common8.Module)({})
|
|
264
512
|
], ExceptionHandlerModule);
|
|
513
|
+
function initializeFormatters(service) {
|
|
514
|
+
service.registerFormatter(new PrismaExceptionFormatter());
|
|
515
|
+
service.registerFormatter(new DtoExceptionFormatter());
|
|
516
|
+
service.registerFormatter(new HttpExceptionFormatter());
|
|
517
|
+
service.registerFormatter(new UnknownExceptionFormatter());
|
|
518
|
+
}
|
|
265
519
|
// Annotate the CommonJS export names for ESM import in node:
|
|
266
520
|
0 && (module.exports = {
|
|
267
521
|
DtoValidationFormatter,
|
|
268
522
|
ExceptionHandlerModule,
|
|
269
523
|
GlobalExceptionFilter,
|
|
270
524
|
OtherExceptionFormatter,
|
|
271
|
-
PrismaExceptionFormatter
|
|
525
|
+
PrismaExceptionFormatter,
|
|
526
|
+
initializeFormatters
|
|
272
527
|
});
|
|
273
528
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/formatters/prisma-exception.formatter.ts","../src/formatters/dto-validation.formatter.ts","../src/formatters/other-exception.formatter.ts","../src/exception-filter/global-exception.filter.ts","../src/exception-handler.module.ts"],"sourcesContent":["// Interfaces\nexport * from './interfaces';\n\n// Formatters\nexport * from './formatters/prisma-exception.formatter';\nexport * from './formatters/dto-validation.formatter';\nexport * from './formatters/other-exception.formatter';\n\n// Filters\nexport * from './exception-filter/global-exception.filter';\n\n// Module\nexport * from './exception-handler.module';\n","import { Injectable } from '@nestjs/common';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ntype PrismaError =\n | PrismaClientKnownRequestError\n | PrismaClientValidationError\n | PrismaClientRustPanicError\n | PrismaClientInitializationError\n | unknown;\n\n@Injectable()\nexport class PrismaExceptionFormatter {\n formatError(exception: PrismaError): IErrorMessage[] {\n if (exception instanceof PrismaClientKnownRequestError) {\n return this.formatPrismaError(exception);\n }\n\n if (\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError\n ) {\n return this.formatQueryError(exception);\n }\n\n if (exception instanceof PrismaClientInitializationError) {\n return this.formatInitializationError(exception);\n }\n\n return this.formatUnknownError(exception);\n }\n\n private formatPrismaError(exception: PrismaClientKnownRequestError): IErrorMessage[] {\n const code = exception.code;\n const meta = exception.meta as Record<string, unknown> | undefined;\n\n switch (code) {\n case 'P2002': {\n const target = meta?.target as string[] | undefined;\n const field = target?.[0] || 'field';\n return [\n {\n path: field,\n message: `A record with this ${field} already exists.`,\n },\n ];\n }\n case 'P2003': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The referenced ${fieldName || 'record'} does not exist.`,\n },\n ];\n }\n case 'P2005': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The value for ${fieldName || 'field'} is invalid.`,\n },\n ];\n }\n case 'P2006': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The ${fieldName || 'field'} field is required.`,\n },\n ];\n }\n case 'P2025': {\n return [\n {\n path: 'record',\n message: 'The requested record does not exist.',\n },\n ];\n }\n default:\n return [\n {\n path: 'database',\n message: 'Database operation failed.',\n },\n ];\n }\n }\n\n private formatQueryError(\n exception: PrismaClientValidationError | PrismaClientRustPanicError,\n ): IErrorMessage[] {\n let message = 'Invalid database query.';\n\n if (exception instanceof PrismaClientRustPanicError) {\n message = 'Database engine panic occurred.';\n }\n\n return [\n {\n path: 'database',\n message,\n },\n ];\n }\n\n private formatInitializationError(exception: PrismaClientInitializationError): IErrorMessage[] {\n return [\n {\n path: 'database',\n message: `Database initialization error: ${exception.message}`,\n },\n ];\n }\n\n private formatUnknownError(exception: unknown): IErrorMessage[] {\n return [\n {\n path: 'unknown',\n message:\n exception instanceof Error ? exception.message : 'An unexpected database error occurred.',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { HttpException } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ninterface ValidationError {\n property: string;\n constraints?: Record<string, string>;\n children?: ValidationError[];\n}\n\n@Injectable()\nexport class DtoValidationFormatter {\n formatDtoValidationException(exception: HttpException): IErrorMessage[] {\n const responseBody: unknown = exception.getResponse();\n\n if (\n typeof responseBody === 'object' &&\n responseBody !== null &&\n 'message' in responseBody &&\n Array.isArray((responseBody as Record<string, unknown>).message)\n ) {\n const messages = (responseBody as Record<string, unknown>).message as unknown[];\n const firstMessage = messages[0];\n\n if (\n firstMessage &&\n typeof firstMessage === 'object' &&\n firstMessage !== null &&\n 'property' in firstMessage\n ) {\n const validationErrors = messages as ValidationError[];\n return validationErrors.map((error: ValidationError) => ({\n path: error.property,\n message: error.constraints\n ? Object.values(error.constraints).join(', ')\n : 'Validation error',\n }));\n }\n }\n\n return [\n {\n path: 'http_error',\n message:\n typeof responseBody === 'object' && responseBody !== null && 'message' in responseBody\n ? String((responseBody as Record<string, unknown>).message)\n : 'An HTTP error occurred',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Injectable()\nexport class OtherExceptionFormatter {\n formatOtherError(exception: unknown): IErrorMessage[] {\n if (\n exception &&\n typeof exception === 'object' &&\n 'path' in exception &&\n 'message' in exception\n ) {\n return [\n {\n path: String((exception as Record<string, unknown>).path),\n message: String((exception as Record<string, unknown>).message),\n },\n ];\n }\n\n const message =\n exception && typeof exception === 'object' && 'message' in exception\n ? String((exception as Record<string, unknown>).message)\n : 'An unexpected error occurred';\n\n return [\n {\n path: 'unknown',\n message,\n },\n ];\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientUnknownRequestError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from '../formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from '../formatters/other-exception.formatter';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n constructor(\n private readonly prismaExceptionFormatter: PrismaExceptionFormatter,\n private readonly dtoValidationFormatter: DtoValidationFormatter,\n private readonly otherValidationFormatter: OtherExceptionFormatter,\n ) {}\n\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n\n private getErrorMessage(exception: unknown): string {\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n return 'Database error';\n }\n\n if (exception instanceof HttpException) {\n return (exception as HttpException).message || 'HTTP error';\n }\n\n return 'Internal server error';\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const status =\n exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;\n\n let errorMessages: IErrorMessage[] = [{ path: 'unknown', message: 'Internal server error' }];\n\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n errorMessages = this.prismaExceptionFormatter.formatError(exception);\n } else if (exception instanceof HttpException) {\n errorMessages = this.dtoValidationFormatter.formatDtoValidationException(\n exception as HttpException,\n );\n } else {\n errorMessages = this.otherValidationFormatter.formatOtherError(exception);\n }\n\n this.logger.error(\n `${request.method} ${request.url}`,\n JSON.stringify(errorMessages),\n 'ExceptionFilter',\n );\n\n response.status(status).json({\n success: false,\n message: this.getErrorMessage(exception),\n errorMessages,\n });\n }\n}\n","import { Module } from '@nestjs/common';\nimport { GlobalExceptionFilter } from './exception-filter/global-exception.filter';\nimport { PrismaExceptionFormatter } from './formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from './formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from './formatters/other-exception.formatter';\n\n@Module({\n providers: [\n GlobalExceptionFilter,\n PrismaExceptionFormatter,\n DtoValidationFormatter,\n OtherExceptionFormatter,\n ],\n exports: [GlobalExceptionFilter],\n})\nexport class ExceptionHandlerModule {}\n"],"mappings":"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","names":["import_common","import_common","import_common","import_library","import_common"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/formatters/prisma-exception.formatter.ts","../src/formatters/dto-validation.formatter.ts","../src/formatters/other-exception.formatter.ts","../src/exception-filter/global-exception.filter.ts","../src/module/exception-handler.module.ts","../src/services/exception-handler.service.ts","../src/constants/default-messages.ts","../src/formatters/unknown-exception.formatter.ts","../src/filter/global-exception.filter.ts","../src/formatters/dto-exception.formatter.ts","../src/formatters/http-exception.formatter.ts"],"sourcesContent":["// Interfaces\nexport * from './interfaces';\n\n// Formatters\nexport * from './formatters/prisma-exception.formatter';\nexport * from './formatters/dto-validation.formatter';\nexport * from './formatters/other-exception.formatter';\n\n// Filters\nexport * from './exception-filter/global-exception.filter';\n\n// Module\nexport * from './module/exception-handler.module';\n","import { Injectable } from '@nestjs/common';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\n\ntype PrismaError =\n | PrismaClientKnownRequestError\n | PrismaClientValidationError\n | PrismaClientRustPanicError\n | PrismaClientInitializationError\n | unknown;\n\n@Injectable()\nexport class PrismaExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n return (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientInitializationError\n );\n }\n\n format(exception: unknown): IErrorMessage[] {\n return this.formatError(exception as PrismaError);\n }\n\n message(_exception: unknown): string {\n return 'Database error';\n }\n\n formatError(exception: PrismaError): IErrorMessage[] {\n if (exception instanceof PrismaClientKnownRequestError) {\n return this.formatPrismaError(exception);\n }\n\n if (\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError\n ) {\n return this.formatQueryError(exception);\n }\n\n if (exception instanceof PrismaClientInitializationError) {\n return this.formatInitializationError(exception);\n }\n\n return this.formatUnknownError(exception);\n }\n\n private formatPrismaError(exception: PrismaClientKnownRequestError): IErrorMessage[] {\n const code = exception.code;\n const meta = exception.meta as Record<string, unknown> | undefined;\n\n switch (code) {\n case 'P2002': {\n const target = meta?.target as string[] | undefined;\n const field = target?.[0] || 'field';\n return [\n {\n path: field,\n message: `A record with this ${field} already exists.`,\n },\n ];\n }\n case 'P2003': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The referenced ${fieldName || 'record'} does not exist.`,\n },\n ];\n }\n case 'P2005': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The value for ${fieldName || 'field'} is invalid.`,\n },\n ];\n }\n case 'P2006': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The ${fieldName || 'field'} field is required.`,\n },\n ];\n }\n case 'P2025': {\n return [\n {\n path: 'record',\n message: 'The requested record does not exist.',\n },\n ];\n }\n default:\n return [\n {\n path: 'database',\n message: 'Database operation failed.',\n },\n ];\n }\n }\n\n private formatQueryError(\n exception: PrismaClientValidationError | PrismaClientRustPanicError,\n ): IErrorMessage[] {\n let message = 'Invalid database query.';\n\n if (exception instanceof PrismaClientRustPanicError) {\n message = 'Database engine panic occurred.';\n }\n\n return [\n {\n path: 'database',\n message,\n },\n ];\n }\n\n private formatInitializationError(exception: PrismaClientInitializationError): IErrorMessage[] {\n return [\n {\n path: 'database',\n message: `Database initialization error: ${exception.message}`,\n },\n ];\n }\n\n private formatUnknownError(exception: unknown): IErrorMessage[] {\n return [\n {\n path: 'unknown',\n message:\n exception instanceof Error ? exception.message : 'An unexpected database error occurred.',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { HttpException } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ninterface ValidationError {\n property: string;\n constraints?: Record<string, string>;\n children?: ValidationError[];\n}\n\n@Injectable()\nexport class DtoValidationFormatter {\n formatDtoValidationException(exception: HttpException): IErrorMessage[] {\n const responseBody: unknown = exception.getResponse();\n\n if (\n typeof responseBody === 'object' &&\n responseBody !== null &&\n 'message' in responseBody &&\n Array.isArray((responseBody as Record<string, unknown>).message)\n ) {\n const messages = (responseBody as Record<string, unknown>).message as unknown[];\n const firstMessage = messages[0];\n\n if (\n firstMessage &&\n typeof firstMessage === 'object' &&\n firstMessage !== null &&\n 'property' in firstMessage\n ) {\n const validationErrors = messages as ValidationError[];\n return validationErrors.map((error: ValidationError) => ({\n path: error.property,\n message: error.constraints\n ? Object.values(error.constraints).join(', ')\n : 'Validation error',\n }));\n }\n }\n\n return [\n {\n path: 'http_error',\n message:\n typeof responseBody === 'object' && responseBody !== null && 'message' in responseBody\n ? String((responseBody as Record<string, unknown>).message)\n : 'An HTTP error occurred',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Injectable()\nexport class OtherExceptionFormatter {\n formatOtherError(exception: unknown): IErrorMessage[] {\n if (\n exception &&\n typeof exception === 'object' &&\n 'path' in exception &&\n 'message' in exception\n ) {\n return [\n {\n path: String((exception as Record<string, unknown>).path),\n message: String((exception as Record<string, unknown>).message),\n },\n ];\n }\n\n const message =\n exception && typeof exception === 'object' && 'message' in exception\n ? String((exception as Record<string, unknown>).message)\n : 'An unexpected error occurred';\n\n return [\n {\n path: 'unknown',\n message,\n },\n ];\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientUnknownRequestError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from '../formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from '../formatters/other-exception.formatter';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n constructor(\n private readonly prismaExceptionFormatter: PrismaExceptionFormatter,\n private readonly dtoValidationFormatter: DtoValidationFormatter,\n private readonly otherValidationFormatter: OtherExceptionFormatter,\n ) {}\n\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n\n private getErrorMessage(exception: unknown): string {\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n return 'Database error';\n }\n\n if (exception instanceof HttpException) {\n return (exception as HttpException).message || 'HTTP error';\n }\n\n return 'Internal server error';\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const status =\n exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;\n\n let errorMessages: IErrorMessage[] = [{ path: 'unknown', message: 'Internal server error' }];\n\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n errorMessages = this.prismaExceptionFormatter.formatError(exception);\n } else if (exception instanceof HttpException) {\n errorMessages = this.dtoValidationFormatter.formatDtoValidationException(\n exception as HttpException,\n );\n } else {\n errorMessages = this.otherValidationFormatter.formatOtherError(exception);\n }\n\n this.logger.error(\n `${request.method} ${request.url}`,\n JSON.stringify(errorMessages),\n 'ExceptionFilter',\n );\n\n response.status(status).json({\n success: false,\n message: this.getErrorMessage(exception),\n errorMessages,\n });\n }\n}\n","import { DynamicModule, Module } from '@nestjs/common';\nimport { ExceptionHandlerService } from '../services/exception-handler.service';\nimport { GlobalExceptionFilter } from '../filter/global-exception.filter';\nimport { ExceptionHandlerConfig } from '../interfaces/exception-handler-config.interface';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoExceptionFormatter } from '../formatters/dto-exception.formatter';\nimport { HttpExceptionFormatter } from '../formatters/http-exception.formatter';\nimport { UnknownExceptionFormatter } from '../formatters/unknown-exception.formatter';\n\n@Module({})\nexport class ExceptionHandlerModule {\n static forRoot(config?: ExceptionHandlerConfig): DynamicModule {\n const providers = [\n ExceptionHandlerService,\n {\n provide: GlobalExceptionFilter,\n useFactory: (service: ExceptionHandlerService) => {\n return new GlobalExceptionFilter(service, config);\n },\n inject: [ExceptionHandlerService],\n },\n ];\n\n return {\n module: ExceptionHandlerModule,\n providers,\n exports: [ExceptionHandlerService, GlobalExceptionFilter],\n global: true,\n };\n }\n\n static forFeature(config?: ExceptionHandlerConfig): DynamicModule {\n return this.forRoot(config);\n }\n}\n\n// Initialize formatters\nexport function initializeFormatters(service: ExceptionHandlerService): void {\n service.registerFormatter(new PrismaExceptionFormatter());\n service.registerFormatter(new DtoExceptionFormatter());\n service.registerFormatter(new HttpExceptionFormatter());\n service.registerFormatter(new UnknownExceptionFormatter());\n}\n","import { Injectable } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\nimport { UnknownExceptionFormatter } from '../formatters/unknown-exception.formatter';\n\n@Injectable()\nexport class ExceptionHandlerService {\n private formatters: ExceptionFormatter[] = [];\n private defaultFormatter: ExceptionFormatter;\n\n constructor() {\n this.defaultFormatter = new UnknownExceptionFormatter();\n }\n\n registerFormatter(formatter: ExceptionFormatter): void {\n this.formatters.push(formatter);\n }\n\n getFormatter(exception: unknown): ExceptionFormatter {\n for (const formatter of this.formatters) {\n if (formatter.supports(exception)) {\n return formatter;\n }\n }\n return this.defaultFormatter;\n }\n\n formatException(exception: unknown): { errors: ErrorMessage[]; message: string } {\n const formatter = this.getFormatter(exception);\n const errors = formatter.format(exception);\n const message = formatter.message(exception);\n\n return { errors, message };\n }\n\n formatErrors(exception: unknown): ErrorMessage[] {\n const formatter = this.getFormatter(exception);\n return formatter.format(exception);\n }\n\n getErrorMessage(exception: unknown): string {\n const formatter = this.getFormatter(exception);\n return formatter.message(exception);\n }\n\n getAllFormatters(): ExceptionFormatter[] {\n return [...this.formatters];\n }\n}\n","export const DEFAULT_ERROR_MESSAGES = {\n UNKNOWN_ERROR: 'An unexpected error occurred',\n VALIDATION_ERROR: 'Validation failed',\n DATABASE_ERROR: 'Database error',\n NOT_FOUND: 'Resource not found',\n UNAUTHORIZED: 'Unauthorized access',\n FORBIDDEN: 'Access forbidden',\n CONFLICT: 'Conflict occurred',\n BAD_REQUEST: 'Bad request',\n};\n\nexport const PRISMA_ERROR_MESSAGES: Record<string, string> = {\n P2002: 'A record with this {field} already exists.',\n P2003: 'This {field} does not exist.',\n P2005: 'Invalid value for {field}.',\n P2006: 'Invalid format for {field}.',\n P2025: 'Record not found.',\n};\n\nexport const DEFAULT_PATH = 'unknown';\n","import { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\nimport { DEFAULT_PATH } from '../constants/default-messages';\n\nexport class UnknownExceptionFormatter implements ExceptionFormatter {\n supports(_exception: unknown): boolean {\n return true;\n }\n\n format(_exception: unknown): ErrorMessage[] {\n return [\n {\n path: DEFAULT_PATH,\n message: 'Internal server error',\n },\n ];\n }\n\n message(_exception: unknown): string {\n return 'Internal server error';\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { ExceptionHandlerService } from '../services/exception-handler.service';\nimport { StandardErrorResponse } from '../interfaces/error-message.interface';\nimport { ExceptionHandlerConfig } from '../interfaces/exception-handler-config.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n private config: ExceptionHandlerConfig;\n\n constructor(\n private exceptionHandlerService: ExceptionHandlerService,\n config?: ExceptionHandlerConfig,\n ) {\n this.config = config || { enableLogging: true, hideStackTrace: false };\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const { errors, message } = this.exceptionHandlerService.formatException(exception);\n const status = this.getStatusCode(exception);\n\n const errorResponse: StandardErrorResponse = {\n success: false,\n message,\n errorMessages: errors,\n };\n\n if (this.config.enableLogging) {\n this.logError(request, status, errors, exception);\n }\n\n response.status(status).json(errorResponse);\n }\n\n private getStatusCode(exception: unknown): number {\n if (exception instanceof HttpException) {\n return exception.getStatus();\n }\n return HttpStatus.INTERNAL_SERVER_ERROR;\n }\n\n private logError(\n request: Request,\n status: number,\n errorMessages: { path: string; message: string }[],\n exception: unknown,\n ): void {\n const method = request.method;\n const url = request.url;\n const timestamp = new Date().toISOString();\n\n const logData = {\n timestamp,\n method,\n url,\n status,\n errorMessages,\n stack: this.config.hideStackTrace ? undefined : (exception as Error)?.stack,\n };\n\n this.logger.error(`${method} ${url} - ${status}`, JSON.stringify(logData));\n }\n}\n","import { ValidationError } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\n\nexport class DtoExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n if (!exception || typeof exception !== 'object') {\n return false;\n }\n\n const error = exception as Record<string, unknown>;\n return (\n Array.isArray(error.validationErrors) ||\n (Array.isArray(error.children) && error.constraints !== undefined)\n );\n }\n\n format(exception: unknown): ErrorMessage[] {\n const error = exception as Record<string, unknown>;\n const validationErrors = error.validationErrors as ValidationError[] | undefined;\n const children = error.children as ValidationError[] | undefined;\n\n if (validationErrors) {\n return this.formatValidationErrors(validationErrors);\n }\n\n if (children) {\n return this.formatChildrenErrors(children);\n }\n\n return [{ path: 'unknown', message: 'Validation failed' }];\n }\n\n message(exception: unknown): string {\n const error = exception as Record<string, unknown>;\n const validationErrors = error.validationErrors as ValidationError[] | undefined;\n const children = error.children as ValidationError[] | undefined;\n\n if (validationErrors && validationErrors.length > 0) {\n const firstError = validationErrors[0];\n const constraints = firstError.constraints;\n if (constraints) {\n return Object.values(constraints)[0];\n }\n }\n\n if (children && children.length > 0) {\n return 'Validation failed for nested fields';\n }\n\n return 'Validation failed';\n }\n\n private formatValidationErrors(errors: ValidationError[]): ErrorMessage[] {\n return errors.flatMap((error) => {\n const constraints = error.constraints;\n if (constraints) {\n return Object.entries(constraints).map(([, value]) => ({\n path: error.property,\n message: value,\n }));\n }\n return [];\n });\n }\n\n private formatChildrenErrors(children: ValidationError[]): ErrorMessage[] {\n return children.flatMap((child) => {\n const constraints = child.constraints;\n if (constraints) {\n return Object.entries(constraints).map(([, value]) => ({\n path: child.property,\n message: value,\n }));\n }\n return [];\n });\n }\n}\n","import { HttpException } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\n\nexport class HttpExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n return exception instanceof HttpException;\n }\n\n format(exception: unknown): ErrorMessage[] {\n const httpException = exception as HttpException;\n const response = httpException.getResponse();\n\n if (typeof response === 'string') {\n return [{ path: 'unknown', message: response }];\n }\n\n if (typeof response === 'object' && response !== null) {\n const responseObj = response as Record<string, unknown>;\n\n if (responseObj.message && Array.isArray(responseObj.message)) {\n // Handle validation errors from class-validator in HTTP exceptions\n return (responseObj.message as string[]).map((msg) => ({\n path: 'unknown',\n message: msg,\n }));\n }\n\n if (responseObj.message && typeof responseObj.message === 'string') {\n return [{ path: 'unknown', message: responseObj.message }];\n }\n\n if (responseObj.error && typeof responseObj.error === 'string') {\n return [{ path: 'unknown', message: responseObj.error }];\n }\n }\n\n return [{ path: 'unknown', message: 'An error occurred' }];\n }\n\n message(exception: unknown): string {\n const httpException = exception as HttpException;\n const response = httpException.getResponse();\n\n if (typeof response === 'string') {\n return response;\n }\n\n if (typeof response === 'object' && response !== null) {\n const responseObj = response as Record<string, unknown>;\n\n if (responseObj.message && typeof responseObj.message === 'string') {\n return responseObj.message;\n }\n\n if (responseObj.error && typeof responseObj.error === 'string') {\n return responseObj.error;\n }\n }\n\n return 'An error occurred';\n }\n}\n"],"mappings":"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","names":["import_common","import_common","import_common","import_library","import_common","import_common","import_common","GlobalExceptionFilter","import_common","GlobalExceptionFilter"]}
|
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,15 @@ import {
|
|
|
19
19
|
PrismaClientInitializationError
|
|
20
20
|
} from "@prisma/client/runtime/library";
|
|
21
21
|
var PrismaExceptionFormatter = class {
|
|
22
|
+
supports(exception) {
|
|
23
|
+
return exception instanceof PrismaClientKnownRequestError || exception instanceof PrismaClientValidationError || exception instanceof PrismaClientRustPanicError || exception instanceof PrismaClientInitializationError;
|
|
24
|
+
}
|
|
25
|
+
format(exception) {
|
|
26
|
+
return this.formatError(exception);
|
|
27
|
+
}
|
|
28
|
+
message(_exception) {
|
|
29
|
+
return "Database error";
|
|
30
|
+
}
|
|
22
31
|
formatError(exception) {
|
|
23
32
|
if (exception instanceof PrismaClientKnownRequestError) {
|
|
24
33
|
return this.formatPrismaError(exception);
|
|
@@ -236,26 +245,276 @@ GlobalExceptionFilter = __decorateClass([
|
|
|
236
245
|
Catch()
|
|
237
246
|
], GlobalExceptionFilter);
|
|
238
247
|
|
|
239
|
-
// src/exception-handler.module.ts
|
|
248
|
+
// src/module/exception-handler.module.ts
|
|
240
249
|
import { Module } from "@nestjs/common";
|
|
250
|
+
|
|
251
|
+
// src/services/exception-handler.service.ts
|
|
252
|
+
import { Injectable as Injectable4 } from "@nestjs/common";
|
|
253
|
+
|
|
254
|
+
// src/constants/default-messages.ts
|
|
255
|
+
var DEFAULT_PATH = "unknown";
|
|
256
|
+
|
|
257
|
+
// src/formatters/unknown-exception.formatter.ts
|
|
258
|
+
var UnknownExceptionFormatter = class {
|
|
259
|
+
supports(_exception) {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
format(_exception) {
|
|
263
|
+
return [
|
|
264
|
+
{
|
|
265
|
+
path: DEFAULT_PATH,
|
|
266
|
+
message: "Internal server error"
|
|
267
|
+
}
|
|
268
|
+
];
|
|
269
|
+
}
|
|
270
|
+
message(_exception) {
|
|
271
|
+
return "Internal server error";
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/services/exception-handler.service.ts
|
|
276
|
+
var ExceptionHandlerService = class {
|
|
277
|
+
constructor() {
|
|
278
|
+
this.formatters = [];
|
|
279
|
+
this.defaultFormatter = new UnknownExceptionFormatter();
|
|
280
|
+
}
|
|
281
|
+
registerFormatter(formatter) {
|
|
282
|
+
this.formatters.push(formatter);
|
|
283
|
+
}
|
|
284
|
+
getFormatter(exception) {
|
|
285
|
+
for (const formatter of this.formatters) {
|
|
286
|
+
if (formatter.supports(exception)) {
|
|
287
|
+
return formatter;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return this.defaultFormatter;
|
|
291
|
+
}
|
|
292
|
+
formatException(exception) {
|
|
293
|
+
const formatter = this.getFormatter(exception);
|
|
294
|
+
const errors = formatter.format(exception);
|
|
295
|
+
const message = formatter.message(exception);
|
|
296
|
+
return { errors, message };
|
|
297
|
+
}
|
|
298
|
+
formatErrors(exception) {
|
|
299
|
+
const formatter = this.getFormatter(exception);
|
|
300
|
+
return formatter.format(exception);
|
|
301
|
+
}
|
|
302
|
+
getErrorMessage(exception) {
|
|
303
|
+
const formatter = this.getFormatter(exception);
|
|
304
|
+
return formatter.message(exception);
|
|
305
|
+
}
|
|
306
|
+
getAllFormatters() {
|
|
307
|
+
return [...this.formatters];
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
ExceptionHandlerService = __decorateClass([
|
|
311
|
+
Injectable4()
|
|
312
|
+
], ExceptionHandlerService);
|
|
313
|
+
|
|
314
|
+
// src/filter/global-exception.filter.ts
|
|
315
|
+
import {
|
|
316
|
+
Catch as Catch2,
|
|
317
|
+
HttpException as HttpException2,
|
|
318
|
+
HttpStatus as HttpStatus2,
|
|
319
|
+
Logger as Logger2
|
|
320
|
+
} from "@nestjs/common";
|
|
321
|
+
var GlobalExceptionFilter2 = class {
|
|
322
|
+
constructor(exceptionHandlerService, config) {
|
|
323
|
+
this.exceptionHandlerService = exceptionHandlerService;
|
|
324
|
+
this.logger = new Logger2(GlobalExceptionFilter2.name);
|
|
325
|
+
this.config = config || { enableLogging: true, hideStackTrace: false };
|
|
326
|
+
}
|
|
327
|
+
catch(exception, host) {
|
|
328
|
+
const ctx = host.switchToHttp();
|
|
329
|
+
const response = ctx.getResponse();
|
|
330
|
+
const request = ctx.getRequest();
|
|
331
|
+
const { errors, message } = this.exceptionHandlerService.formatException(exception);
|
|
332
|
+
const status = this.getStatusCode(exception);
|
|
333
|
+
const errorResponse = {
|
|
334
|
+
success: false,
|
|
335
|
+
message,
|
|
336
|
+
errorMessages: errors
|
|
337
|
+
};
|
|
338
|
+
if (this.config.enableLogging) {
|
|
339
|
+
this.logError(request, status, errors, exception);
|
|
340
|
+
}
|
|
341
|
+
response.status(status).json(errorResponse);
|
|
342
|
+
}
|
|
343
|
+
getStatusCode(exception) {
|
|
344
|
+
if (exception instanceof HttpException2) {
|
|
345
|
+
return exception.getStatus();
|
|
346
|
+
}
|
|
347
|
+
return HttpStatus2.INTERNAL_SERVER_ERROR;
|
|
348
|
+
}
|
|
349
|
+
logError(request, status, errorMessages, exception) {
|
|
350
|
+
const method = request.method;
|
|
351
|
+
const url = request.url;
|
|
352
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
353
|
+
const logData = {
|
|
354
|
+
timestamp,
|
|
355
|
+
method,
|
|
356
|
+
url,
|
|
357
|
+
status,
|
|
358
|
+
errorMessages,
|
|
359
|
+
stack: this.config.hideStackTrace ? void 0 : exception?.stack
|
|
360
|
+
};
|
|
361
|
+
this.logger.error(`${method} ${url} - ${status}`, JSON.stringify(logData));
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
GlobalExceptionFilter2 = __decorateClass([
|
|
365
|
+
Catch2()
|
|
366
|
+
], GlobalExceptionFilter2);
|
|
367
|
+
|
|
368
|
+
// src/formatters/dto-exception.formatter.ts
|
|
369
|
+
var DtoExceptionFormatter = class {
|
|
370
|
+
supports(exception) {
|
|
371
|
+
if (!exception || typeof exception !== "object") {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
const error = exception;
|
|
375
|
+
return Array.isArray(error.validationErrors) || Array.isArray(error.children) && error.constraints !== void 0;
|
|
376
|
+
}
|
|
377
|
+
format(exception) {
|
|
378
|
+
const error = exception;
|
|
379
|
+
const validationErrors = error.validationErrors;
|
|
380
|
+
const children = error.children;
|
|
381
|
+
if (validationErrors) {
|
|
382
|
+
return this.formatValidationErrors(validationErrors);
|
|
383
|
+
}
|
|
384
|
+
if (children) {
|
|
385
|
+
return this.formatChildrenErrors(children);
|
|
386
|
+
}
|
|
387
|
+
return [{ path: "unknown", message: "Validation failed" }];
|
|
388
|
+
}
|
|
389
|
+
message(exception) {
|
|
390
|
+
const error = exception;
|
|
391
|
+
const validationErrors = error.validationErrors;
|
|
392
|
+
const children = error.children;
|
|
393
|
+
if (validationErrors && validationErrors.length > 0) {
|
|
394
|
+
const firstError = validationErrors[0];
|
|
395
|
+
const constraints = firstError.constraints;
|
|
396
|
+
if (constraints) {
|
|
397
|
+
return Object.values(constraints)[0];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (children && children.length > 0) {
|
|
401
|
+
return "Validation failed for nested fields";
|
|
402
|
+
}
|
|
403
|
+
return "Validation failed";
|
|
404
|
+
}
|
|
405
|
+
formatValidationErrors(errors) {
|
|
406
|
+
return errors.flatMap((error) => {
|
|
407
|
+
const constraints = error.constraints;
|
|
408
|
+
if (constraints) {
|
|
409
|
+
return Object.entries(constraints).map(([, value]) => ({
|
|
410
|
+
path: error.property,
|
|
411
|
+
message: value
|
|
412
|
+
}));
|
|
413
|
+
}
|
|
414
|
+
return [];
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
formatChildrenErrors(children) {
|
|
418
|
+
return children.flatMap((child) => {
|
|
419
|
+
const constraints = child.constraints;
|
|
420
|
+
if (constraints) {
|
|
421
|
+
return Object.entries(constraints).map(([, value]) => ({
|
|
422
|
+
path: child.property,
|
|
423
|
+
message: value
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
return [];
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// src/formatters/http-exception.formatter.ts
|
|
432
|
+
import { HttpException as HttpException3 } from "@nestjs/common";
|
|
433
|
+
var HttpExceptionFormatter = class {
|
|
434
|
+
supports(exception) {
|
|
435
|
+
return exception instanceof HttpException3;
|
|
436
|
+
}
|
|
437
|
+
format(exception) {
|
|
438
|
+
const httpException = exception;
|
|
439
|
+
const response = httpException.getResponse();
|
|
440
|
+
if (typeof response === "string") {
|
|
441
|
+
return [{ path: "unknown", message: response }];
|
|
442
|
+
}
|
|
443
|
+
if (typeof response === "object" && response !== null) {
|
|
444
|
+
const responseObj = response;
|
|
445
|
+
if (responseObj.message && Array.isArray(responseObj.message)) {
|
|
446
|
+
return responseObj.message.map((msg) => ({
|
|
447
|
+
path: "unknown",
|
|
448
|
+
message: msg
|
|
449
|
+
}));
|
|
450
|
+
}
|
|
451
|
+
if (responseObj.message && typeof responseObj.message === "string") {
|
|
452
|
+
return [{ path: "unknown", message: responseObj.message }];
|
|
453
|
+
}
|
|
454
|
+
if (responseObj.error && typeof responseObj.error === "string") {
|
|
455
|
+
return [{ path: "unknown", message: responseObj.error }];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return [{ path: "unknown", message: "An error occurred" }];
|
|
459
|
+
}
|
|
460
|
+
message(exception) {
|
|
461
|
+
const httpException = exception;
|
|
462
|
+
const response = httpException.getResponse();
|
|
463
|
+
if (typeof response === "string") {
|
|
464
|
+
return response;
|
|
465
|
+
}
|
|
466
|
+
if (typeof response === "object" && response !== null) {
|
|
467
|
+
const responseObj = response;
|
|
468
|
+
if (responseObj.message && typeof responseObj.message === "string") {
|
|
469
|
+
return responseObj.message;
|
|
470
|
+
}
|
|
471
|
+
if (responseObj.error && typeof responseObj.error === "string") {
|
|
472
|
+
return responseObj.error;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return "An error occurred";
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
// src/module/exception-handler.module.ts
|
|
241
480
|
var ExceptionHandlerModule = class {
|
|
481
|
+
static forRoot(config) {
|
|
482
|
+
const providers = [
|
|
483
|
+
ExceptionHandlerService,
|
|
484
|
+
{
|
|
485
|
+
provide: GlobalExceptionFilter2,
|
|
486
|
+
useFactory: (service) => {
|
|
487
|
+
return new GlobalExceptionFilter2(service, config);
|
|
488
|
+
},
|
|
489
|
+
inject: [ExceptionHandlerService]
|
|
490
|
+
}
|
|
491
|
+
];
|
|
492
|
+
return {
|
|
493
|
+
module: ExceptionHandlerModule,
|
|
494
|
+
providers,
|
|
495
|
+
exports: [ExceptionHandlerService, GlobalExceptionFilter2],
|
|
496
|
+
global: true
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
static forFeature(config) {
|
|
500
|
+
return this.forRoot(config);
|
|
501
|
+
}
|
|
242
502
|
};
|
|
243
503
|
ExceptionHandlerModule = __decorateClass([
|
|
244
|
-
Module({
|
|
245
|
-
providers: [
|
|
246
|
-
GlobalExceptionFilter,
|
|
247
|
-
PrismaExceptionFormatter,
|
|
248
|
-
DtoValidationFormatter,
|
|
249
|
-
OtherExceptionFormatter
|
|
250
|
-
],
|
|
251
|
-
exports: [GlobalExceptionFilter]
|
|
252
|
-
})
|
|
504
|
+
Module({})
|
|
253
505
|
], ExceptionHandlerModule);
|
|
506
|
+
function initializeFormatters(service) {
|
|
507
|
+
service.registerFormatter(new PrismaExceptionFormatter());
|
|
508
|
+
service.registerFormatter(new DtoExceptionFormatter());
|
|
509
|
+
service.registerFormatter(new HttpExceptionFormatter());
|
|
510
|
+
service.registerFormatter(new UnknownExceptionFormatter());
|
|
511
|
+
}
|
|
254
512
|
export {
|
|
255
513
|
DtoValidationFormatter,
|
|
256
514
|
ExceptionHandlerModule,
|
|
257
515
|
GlobalExceptionFilter,
|
|
258
516
|
OtherExceptionFormatter,
|
|
259
|
-
PrismaExceptionFormatter
|
|
517
|
+
PrismaExceptionFormatter,
|
|
518
|
+
initializeFormatters
|
|
260
519
|
};
|
|
261
520
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formatters/prisma-exception.formatter.ts","../src/formatters/dto-validation.formatter.ts","../src/formatters/other-exception.formatter.ts","../src/exception-filter/global-exception.filter.ts","../src/exception-handler.module.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ntype PrismaError =\n | PrismaClientKnownRequestError\n | PrismaClientValidationError\n | PrismaClientRustPanicError\n | PrismaClientInitializationError\n | unknown;\n\n@Injectable()\nexport class PrismaExceptionFormatter {\n formatError(exception: PrismaError): IErrorMessage[] {\n if (exception instanceof PrismaClientKnownRequestError) {\n return this.formatPrismaError(exception);\n }\n\n if (\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError\n ) {\n return this.formatQueryError(exception);\n }\n\n if (exception instanceof PrismaClientInitializationError) {\n return this.formatInitializationError(exception);\n }\n\n return this.formatUnknownError(exception);\n }\n\n private formatPrismaError(exception: PrismaClientKnownRequestError): IErrorMessage[] {\n const code = exception.code;\n const meta = exception.meta as Record<string, unknown> | undefined;\n\n switch (code) {\n case 'P2002': {\n const target = meta?.target as string[] | undefined;\n const field = target?.[0] || 'field';\n return [\n {\n path: field,\n message: `A record with this ${field} already exists.`,\n },\n ];\n }\n case 'P2003': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The referenced ${fieldName || 'record'} does not exist.`,\n },\n ];\n }\n case 'P2005': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The value for ${fieldName || 'field'} is invalid.`,\n },\n ];\n }\n case 'P2006': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The ${fieldName || 'field'} field is required.`,\n },\n ];\n }\n case 'P2025': {\n return [\n {\n path: 'record',\n message: 'The requested record does not exist.',\n },\n ];\n }\n default:\n return [\n {\n path: 'database',\n message: 'Database operation failed.',\n },\n ];\n }\n }\n\n private formatQueryError(\n exception: PrismaClientValidationError | PrismaClientRustPanicError,\n ): IErrorMessage[] {\n let message = 'Invalid database query.';\n\n if (exception instanceof PrismaClientRustPanicError) {\n message = 'Database engine panic occurred.';\n }\n\n return [\n {\n path: 'database',\n message,\n },\n ];\n }\n\n private formatInitializationError(exception: PrismaClientInitializationError): IErrorMessage[] {\n return [\n {\n path: 'database',\n message: `Database initialization error: ${exception.message}`,\n },\n ];\n }\n\n private formatUnknownError(exception: unknown): IErrorMessage[] {\n return [\n {\n path: 'unknown',\n message:\n exception instanceof Error ? exception.message : 'An unexpected database error occurred.',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { HttpException } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ninterface ValidationError {\n property: string;\n constraints?: Record<string, string>;\n children?: ValidationError[];\n}\n\n@Injectable()\nexport class DtoValidationFormatter {\n formatDtoValidationException(exception: HttpException): IErrorMessage[] {\n const responseBody: unknown = exception.getResponse();\n\n if (\n typeof responseBody === 'object' &&\n responseBody !== null &&\n 'message' in responseBody &&\n Array.isArray((responseBody as Record<string, unknown>).message)\n ) {\n const messages = (responseBody as Record<string, unknown>).message as unknown[];\n const firstMessage = messages[0];\n\n if (\n firstMessage &&\n typeof firstMessage === 'object' &&\n firstMessage !== null &&\n 'property' in firstMessage\n ) {\n const validationErrors = messages as ValidationError[];\n return validationErrors.map((error: ValidationError) => ({\n path: error.property,\n message: error.constraints\n ? Object.values(error.constraints).join(', ')\n : 'Validation error',\n }));\n }\n }\n\n return [\n {\n path: 'http_error',\n message:\n typeof responseBody === 'object' && responseBody !== null && 'message' in responseBody\n ? String((responseBody as Record<string, unknown>).message)\n : 'An HTTP error occurred',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Injectable()\nexport class OtherExceptionFormatter {\n formatOtherError(exception: unknown): IErrorMessage[] {\n if (\n exception &&\n typeof exception === 'object' &&\n 'path' in exception &&\n 'message' in exception\n ) {\n return [\n {\n path: String((exception as Record<string, unknown>).path),\n message: String((exception as Record<string, unknown>).message),\n },\n ];\n }\n\n const message =\n exception && typeof exception === 'object' && 'message' in exception\n ? String((exception as Record<string, unknown>).message)\n : 'An unexpected error occurred';\n\n return [\n {\n path: 'unknown',\n message,\n },\n ];\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientUnknownRequestError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from '../formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from '../formatters/other-exception.formatter';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n constructor(\n private readonly prismaExceptionFormatter: PrismaExceptionFormatter,\n private readonly dtoValidationFormatter: DtoValidationFormatter,\n private readonly otherValidationFormatter: OtherExceptionFormatter,\n ) {}\n\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n\n private getErrorMessage(exception: unknown): string {\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n return 'Database error';\n }\n\n if (exception instanceof HttpException) {\n return (exception as HttpException).message || 'HTTP error';\n }\n\n return 'Internal server error';\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const status =\n exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;\n\n let errorMessages: IErrorMessage[] = [{ path: 'unknown', message: 'Internal server error' }];\n\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n errorMessages = this.prismaExceptionFormatter.formatError(exception);\n } else if (exception instanceof HttpException) {\n errorMessages = this.dtoValidationFormatter.formatDtoValidationException(\n exception as HttpException,\n );\n } else {\n errorMessages = this.otherValidationFormatter.formatOtherError(exception);\n }\n\n this.logger.error(\n `${request.method} ${request.url}`,\n JSON.stringify(errorMessages),\n 'ExceptionFilter',\n );\n\n response.status(status).json({\n success: false,\n message: this.getErrorMessage(exception),\n errorMessages,\n });\n }\n}\n","import { Module } from '@nestjs/common';\nimport { GlobalExceptionFilter } from './exception-filter/global-exception.filter';\nimport { PrismaExceptionFormatter } from './formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from './formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from './formatters/other-exception.formatter';\n\n@Module({\n providers: [\n GlobalExceptionFilter,\n PrismaExceptionFormatter,\n DtoValidationFormatter,\n OtherExceptionFormatter,\n ],\n exports: [GlobalExceptionFilter],\n})\nexport class ExceptionHandlerModule {}\n"],"mappings":"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","names":["Injectable","Injectable","Injectable","Injectable","PrismaClientKnownRequestError","PrismaClientValidationError","PrismaClientRustPanicError","PrismaClientInitializationError","PrismaClientKnownRequestError","PrismaClientValidationError","PrismaClientRustPanicError","PrismaClientInitializationError"]}
|
|
1
|
+
{"version":3,"sources":["../src/formatters/prisma-exception.formatter.ts","../src/formatters/dto-validation.formatter.ts","../src/formatters/other-exception.formatter.ts","../src/exception-filter/global-exception.filter.ts","../src/module/exception-handler.module.ts","../src/services/exception-handler.service.ts","../src/constants/default-messages.ts","../src/formatters/unknown-exception.formatter.ts","../src/filter/global-exception.filter.ts","../src/formatters/dto-exception.formatter.ts","../src/formatters/http-exception.formatter.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\n\ntype PrismaError =\n | PrismaClientKnownRequestError\n | PrismaClientValidationError\n | PrismaClientRustPanicError\n | PrismaClientInitializationError\n | unknown;\n\n@Injectable()\nexport class PrismaExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n return (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientInitializationError\n );\n }\n\n format(exception: unknown): IErrorMessage[] {\n return this.formatError(exception as PrismaError);\n }\n\n message(_exception: unknown): string {\n return 'Database error';\n }\n\n formatError(exception: PrismaError): IErrorMessage[] {\n if (exception instanceof PrismaClientKnownRequestError) {\n return this.formatPrismaError(exception);\n }\n\n if (\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError\n ) {\n return this.formatQueryError(exception);\n }\n\n if (exception instanceof PrismaClientInitializationError) {\n return this.formatInitializationError(exception);\n }\n\n return this.formatUnknownError(exception);\n }\n\n private formatPrismaError(exception: PrismaClientKnownRequestError): IErrorMessage[] {\n const code = exception.code;\n const meta = exception.meta as Record<string, unknown> | undefined;\n\n switch (code) {\n case 'P2002': {\n const target = meta?.target as string[] | undefined;\n const field = target?.[0] || 'field';\n return [\n {\n path: field,\n message: `A record with this ${field} already exists.`,\n },\n ];\n }\n case 'P2003': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The referenced ${fieldName || 'record'} does not exist.`,\n },\n ];\n }\n case 'P2005': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The value for ${fieldName || 'field'} is invalid.`,\n },\n ];\n }\n case 'P2006': {\n const fieldName = meta?.field_name as string | undefined;\n return [\n {\n path: fieldName || 'field',\n message: `The ${fieldName || 'field'} field is required.`,\n },\n ];\n }\n case 'P2025': {\n return [\n {\n path: 'record',\n message: 'The requested record does not exist.',\n },\n ];\n }\n default:\n return [\n {\n path: 'database',\n message: 'Database operation failed.',\n },\n ];\n }\n }\n\n private formatQueryError(\n exception: PrismaClientValidationError | PrismaClientRustPanicError,\n ): IErrorMessage[] {\n let message = 'Invalid database query.';\n\n if (exception instanceof PrismaClientRustPanicError) {\n message = 'Database engine panic occurred.';\n }\n\n return [\n {\n path: 'database',\n message,\n },\n ];\n }\n\n private formatInitializationError(exception: PrismaClientInitializationError): IErrorMessage[] {\n return [\n {\n path: 'database',\n message: `Database initialization error: ${exception.message}`,\n },\n ];\n }\n\n private formatUnknownError(exception: unknown): IErrorMessage[] {\n return [\n {\n path: 'unknown',\n message:\n exception instanceof Error ? exception.message : 'An unexpected database error occurred.',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { HttpException } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\ninterface ValidationError {\n property: string;\n constraints?: Record<string, string>;\n children?: ValidationError[];\n}\n\n@Injectable()\nexport class DtoValidationFormatter {\n formatDtoValidationException(exception: HttpException): IErrorMessage[] {\n const responseBody: unknown = exception.getResponse();\n\n if (\n typeof responseBody === 'object' &&\n responseBody !== null &&\n 'message' in responseBody &&\n Array.isArray((responseBody as Record<string, unknown>).message)\n ) {\n const messages = (responseBody as Record<string, unknown>).message as unknown[];\n const firstMessage = messages[0];\n\n if (\n firstMessage &&\n typeof firstMessage === 'object' &&\n firstMessage !== null &&\n 'property' in firstMessage\n ) {\n const validationErrors = messages as ValidationError[];\n return validationErrors.map((error: ValidationError) => ({\n path: error.property,\n message: error.constraints\n ? Object.values(error.constraints).join(', ')\n : 'Validation error',\n }));\n }\n }\n\n return [\n {\n path: 'http_error',\n message:\n typeof responseBody === 'object' && responseBody !== null && 'message' in responseBody\n ? String((responseBody as Record<string, unknown>).message)\n : 'An HTTP error occurred',\n },\n ];\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Injectable()\nexport class OtherExceptionFormatter {\n formatOtherError(exception: unknown): IErrorMessage[] {\n if (\n exception &&\n typeof exception === 'object' &&\n 'path' in exception &&\n 'message' in exception\n ) {\n return [\n {\n path: String((exception as Record<string, unknown>).path),\n message: String((exception as Record<string, unknown>).message),\n },\n ];\n }\n\n const message =\n exception && typeof exception === 'object' && 'message' in exception\n ? String((exception as Record<string, unknown>).message)\n : 'An unexpected error occurred';\n\n return [\n {\n path: 'unknown',\n message,\n },\n ];\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n PrismaClientKnownRequestError,\n PrismaClientValidationError,\n PrismaClientRustPanicError,\n PrismaClientUnknownRequestError,\n PrismaClientInitializationError,\n} from '@prisma/client/runtime/library';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoValidationFormatter } from '../formatters/dto-validation.formatter';\nimport { OtherExceptionFormatter } from '../formatters/other-exception.formatter';\nimport { IErrorMessage } from '../interfaces/error-message.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n constructor(\n private readonly prismaExceptionFormatter: PrismaExceptionFormatter,\n private readonly dtoValidationFormatter: DtoValidationFormatter,\n private readonly otherValidationFormatter: OtherExceptionFormatter,\n ) {}\n\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n\n private getErrorMessage(exception: unknown): string {\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n return 'Database error';\n }\n\n if (exception instanceof HttpException) {\n return (exception as HttpException).message || 'HTTP error';\n }\n\n return 'Internal server error';\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const status =\n exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;\n\n let errorMessages: IErrorMessage[] = [{ path: 'unknown', message: 'Internal server error' }];\n\n if (\n exception instanceof PrismaClientKnownRequestError ||\n exception instanceof PrismaClientValidationError ||\n exception instanceof PrismaClientRustPanicError ||\n exception instanceof PrismaClientUnknownRequestError ||\n exception instanceof PrismaClientInitializationError\n ) {\n errorMessages = this.prismaExceptionFormatter.formatError(exception);\n } else if (exception instanceof HttpException) {\n errorMessages = this.dtoValidationFormatter.formatDtoValidationException(\n exception as HttpException,\n );\n } else {\n errorMessages = this.otherValidationFormatter.formatOtherError(exception);\n }\n\n this.logger.error(\n `${request.method} ${request.url}`,\n JSON.stringify(errorMessages),\n 'ExceptionFilter',\n );\n\n response.status(status).json({\n success: false,\n message: this.getErrorMessage(exception),\n errorMessages,\n });\n }\n}\n","import { DynamicModule, Module } from '@nestjs/common';\nimport { ExceptionHandlerService } from '../services/exception-handler.service';\nimport { GlobalExceptionFilter } from '../filter/global-exception.filter';\nimport { ExceptionHandlerConfig } from '../interfaces/exception-handler-config.interface';\nimport { PrismaExceptionFormatter } from '../formatters/prisma-exception.formatter';\nimport { DtoExceptionFormatter } from '../formatters/dto-exception.formatter';\nimport { HttpExceptionFormatter } from '../formatters/http-exception.formatter';\nimport { UnknownExceptionFormatter } from '../formatters/unknown-exception.formatter';\n\n@Module({})\nexport class ExceptionHandlerModule {\n static forRoot(config?: ExceptionHandlerConfig): DynamicModule {\n const providers = [\n ExceptionHandlerService,\n {\n provide: GlobalExceptionFilter,\n useFactory: (service: ExceptionHandlerService) => {\n return new GlobalExceptionFilter(service, config);\n },\n inject: [ExceptionHandlerService],\n },\n ];\n\n return {\n module: ExceptionHandlerModule,\n providers,\n exports: [ExceptionHandlerService, GlobalExceptionFilter],\n global: true,\n };\n }\n\n static forFeature(config?: ExceptionHandlerConfig): DynamicModule {\n return this.forRoot(config);\n }\n}\n\n// Initialize formatters\nexport function initializeFormatters(service: ExceptionHandlerService): void {\n service.registerFormatter(new PrismaExceptionFormatter());\n service.registerFormatter(new DtoExceptionFormatter());\n service.registerFormatter(new HttpExceptionFormatter());\n service.registerFormatter(new UnknownExceptionFormatter());\n}\n","import { Injectable } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\nimport { UnknownExceptionFormatter } from '../formatters/unknown-exception.formatter';\n\n@Injectable()\nexport class ExceptionHandlerService {\n private formatters: ExceptionFormatter[] = [];\n private defaultFormatter: ExceptionFormatter;\n\n constructor() {\n this.defaultFormatter = new UnknownExceptionFormatter();\n }\n\n registerFormatter(formatter: ExceptionFormatter): void {\n this.formatters.push(formatter);\n }\n\n getFormatter(exception: unknown): ExceptionFormatter {\n for (const formatter of this.formatters) {\n if (formatter.supports(exception)) {\n return formatter;\n }\n }\n return this.defaultFormatter;\n }\n\n formatException(exception: unknown): { errors: ErrorMessage[]; message: string } {\n const formatter = this.getFormatter(exception);\n const errors = formatter.format(exception);\n const message = formatter.message(exception);\n\n return { errors, message };\n }\n\n formatErrors(exception: unknown): ErrorMessage[] {\n const formatter = this.getFormatter(exception);\n return formatter.format(exception);\n }\n\n getErrorMessage(exception: unknown): string {\n const formatter = this.getFormatter(exception);\n return formatter.message(exception);\n }\n\n getAllFormatters(): ExceptionFormatter[] {\n return [...this.formatters];\n }\n}\n","export const DEFAULT_ERROR_MESSAGES = {\n UNKNOWN_ERROR: 'An unexpected error occurred',\n VALIDATION_ERROR: 'Validation failed',\n DATABASE_ERROR: 'Database error',\n NOT_FOUND: 'Resource not found',\n UNAUTHORIZED: 'Unauthorized access',\n FORBIDDEN: 'Access forbidden',\n CONFLICT: 'Conflict occurred',\n BAD_REQUEST: 'Bad request',\n};\n\nexport const PRISMA_ERROR_MESSAGES: Record<string, string> = {\n P2002: 'A record with this {field} already exists.',\n P2003: 'This {field} does not exist.',\n P2005: 'Invalid value for {field}.',\n P2006: 'Invalid format for {field}.',\n P2025: 'Record not found.',\n};\n\nexport const DEFAULT_PATH = 'unknown';\n","import { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\nimport { DEFAULT_PATH } from '../constants/default-messages';\n\nexport class UnknownExceptionFormatter implements ExceptionFormatter {\n supports(_exception: unknown): boolean {\n return true;\n }\n\n format(_exception: unknown): ErrorMessage[] {\n return [\n {\n path: DEFAULT_PATH,\n message: 'Internal server error',\n },\n ];\n }\n\n message(_exception: unknown): string {\n return 'Internal server error';\n }\n}\n","import {\n ExceptionFilter,\n Catch,\n ArgumentsHost,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { ExceptionHandlerService } from '../services/exception-handler.service';\nimport { StandardErrorResponse } from '../interfaces/error-message.interface';\nimport { ExceptionHandlerConfig } from '../interfaces/exception-handler-config.interface';\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n private config: ExceptionHandlerConfig;\n\n constructor(\n private exceptionHandlerService: ExceptionHandlerService,\n config?: ExceptionHandlerConfig,\n ) {\n this.config = config || { enableLogging: true, hideStackTrace: false };\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n const { errors, message } = this.exceptionHandlerService.formatException(exception);\n const status = this.getStatusCode(exception);\n\n const errorResponse: StandardErrorResponse = {\n success: false,\n message,\n errorMessages: errors,\n };\n\n if (this.config.enableLogging) {\n this.logError(request, status, errors, exception);\n }\n\n response.status(status).json(errorResponse);\n }\n\n private getStatusCode(exception: unknown): number {\n if (exception instanceof HttpException) {\n return exception.getStatus();\n }\n return HttpStatus.INTERNAL_SERVER_ERROR;\n }\n\n private logError(\n request: Request,\n status: number,\n errorMessages: { path: string; message: string }[],\n exception: unknown,\n ): void {\n const method = request.method;\n const url = request.url;\n const timestamp = new Date().toISOString();\n\n const logData = {\n timestamp,\n method,\n url,\n status,\n errorMessages,\n stack: this.config.hideStackTrace ? undefined : (exception as Error)?.stack,\n };\n\n this.logger.error(`${method} ${url} - ${status}`, JSON.stringify(logData));\n }\n}\n","import { ValidationError } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\n\nexport class DtoExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n if (!exception || typeof exception !== 'object') {\n return false;\n }\n\n const error = exception as Record<string, unknown>;\n return (\n Array.isArray(error.validationErrors) ||\n (Array.isArray(error.children) && error.constraints !== undefined)\n );\n }\n\n format(exception: unknown): ErrorMessage[] {\n const error = exception as Record<string, unknown>;\n const validationErrors = error.validationErrors as ValidationError[] | undefined;\n const children = error.children as ValidationError[] | undefined;\n\n if (validationErrors) {\n return this.formatValidationErrors(validationErrors);\n }\n\n if (children) {\n return this.formatChildrenErrors(children);\n }\n\n return [{ path: 'unknown', message: 'Validation failed' }];\n }\n\n message(exception: unknown): string {\n const error = exception as Record<string, unknown>;\n const validationErrors = error.validationErrors as ValidationError[] | undefined;\n const children = error.children as ValidationError[] | undefined;\n\n if (validationErrors && validationErrors.length > 0) {\n const firstError = validationErrors[0];\n const constraints = firstError.constraints;\n if (constraints) {\n return Object.values(constraints)[0];\n }\n }\n\n if (children && children.length > 0) {\n return 'Validation failed for nested fields';\n }\n\n return 'Validation failed';\n }\n\n private formatValidationErrors(errors: ValidationError[]): ErrorMessage[] {\n return errors.flatMap((error) => {\n const constraints = error.constraints;\n if (constraints) {\n return Object.entries(constraints).map(([, value]) => ({\n path: error.property,\n message: value,\n }));\n }\n return [];\n });\n }\n\n private formatChildrenErrors(children: ValidationError[]): ErrorMessage[] {\n return children.flatMap((child) => {\n const constraints = child.constraints;\n if (constraints) {\n return Object.entries(constraints).map(([, value]) => ({\n path: child.property,\n message: value,\n }));\n }\n return [];\n });\n }\n}\n","import { HttpException } from '@nestjs/common';\nimport { ExceptionFormatter } from '../interfaces/exception-formatter.interface';\nimport { ErrorMessage } from '../interfaces/error-message.interface';\n\nexport class HttpExceptionFormatter implements ExceptionFormatter {\n supports(exception: unknown): boolean {\n return exception instanceof HttpException;\n }\n\n format(exception: unknown): ErrorMessage[] {\n const httpException = exception as HttpException;\n const response = httpException.getResponse();\n\n if (typeof response === 'string') {\n return [{ path: 'unknown', message: response }];\n }\n\n if (typeof response === 'object' && response !== null) {\n const responseObj = response as Record<string, unknown>;\n\n if (responseObj.message && Array.isArray(responseObj.message)) {\n // Handle validation errors from class-validator in HTTP exceptions\n return (responseObj.message as string[]).map((msg) => ({\n path: 'unknown',\n message: msg,\n }));\n }\n\n if (responseObj.message && typeof responseObj.message === 'string') {\n return [{ path: 'unknown', message: responseObj.message }];\n }\n\n if (responseObj.error && typeof responseObj.error === 'string') {\n return [{ path: 'unknown', message: responseObj.error }];\n }\n }\n\n return [{ path: 'unknown', message: 'An error occurred' }];\n }\n\n message(exception: unknown): string {\n const httpException = exception as HttpException;\n const response = httpException.getResponse();\n\n if (typeof response === 'string') {\n return response;\n }\n\n if (typeof response === 'object' && response !== null) {\n const responseObj = response as Record<string, unknown>;\n\n if (responseObj.message && typeof responseObj.message === 'string') {\n return responseObj.message;\n }\n\n if (responseObj.error && typeof responseObj.error === 'string') {\n return responseObj.error;\n }\n }\n\n return 'An error occurred';\n }\n}\n"],"mappings":"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","names":["Injectable","Injectable","Injectable","Injectable","PrismaClientKnownRequestError","PrismaClientValidationError","PrismaClientRustPanicError","PrismaClientInitializationError","PrismaClientKnownRequestError","PrismaClientValidationError","PrismaClientRustPanicError","PrismaClientInitializationError","Injectable","Injectable","Catch","HttpException","HttpStatus","Logger","GlobalExceptionFilter","Logger","HttpException","HttpStatus","Catch","HttpException","GlobalExceptionFilter"]}
|