@nest-yalc-2/errors 1.3.4

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.
Files changed (64) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +37 -0
  3. package/package.json +42 -0
  4. package/src/__tests__/database-exception.filter.spec.ts +71 -0
  5. package/src/__tests__/default.error.spec.ts +529 -0
  6. package/src/__tests__/error.helper.spec.ts +23 -0
  7. package/src/__tests__/errors.enum.spec.ts +32 -0
  8. package/src/__tests__/http-exception.filter.spec.ts +129 -0
  9. package/src/__tests__/http-status-code-to-errors.spec.ts +26 -0
  10. package/src/__tests__/input-validation.error.spec.ts +27 -0
  11. package/src/__tests__/login.error.spec.ts +23 -0
  12. package/src/__tests__/result.error.spec.ts +47 -0
  13. package/src/__tests__/system-exception.filter.spec.ts +39 -0
  14. package/src/__tests__/tsconfig.json +3 -0
  15. package/src/__tests__/validation-exception.filter.spec.ts +31 -0
  16. package/src/__tests__/verification.error.spec.ts +28 -0
  17. package/src/default.error.d.ts +93 -0
  18. package/src/default.error.js +266 -0
  19. package/src/default.error.js.map +1 -0
  20. package/src/default.error.ts +640 -0
  21. package/src/error.class.d.ts +103 -0
  22. package/src/error.class.js +170 -0
  23. package/src/error.class.js.map +1 -0
  24. package/src/error.class.ts +319 -0
  25. package/src/error.enum.d.ts +29 -0
  26. package/src/error.enum.js +41 -0
  27. package/src/error.enum.js.map +1 -0
  28. package/src/error.enum.ts +45 -0
  29. package/src/error.helper.d.ts +2 -0
  30. package/src/error.helper.js +20 -0
  31. package/src/error.helper.js.map +1 -0
  32. package/src/error.helper.ts +34 -0
  33. package/src/filters/database-exception.filter.d.ts +7 -0
  34. package/src/filters/database-exception.filter.js +74 -0
  35. package/src/filters/database-exception.filter.js.map +1 -0
  36. package/src/filters/database-exception.filter.ts +43 -0
  37. package/src/filters/http-exception.filter.d.ts +16 -0
  38. package/src/filters/http-exception.filter.js +145 -0
  39. package/src/filters/http-exception.filter.js.map +1 -0
  40. package/src/filters/http-exception.filter.ts +143 -0
  41. package/src/filters/index.d.ts +1 -0
  42. package/src/filters/index.js +6 -0
  43. package/src/filters/index.js.map +1 -0
  44. package/src/filters/index.ts +6 -0
  45. package/src/filters/system-exception.filter.d.ts +7 -0
  46. package/src/filters/system-exception.filter.js +29 -0
  47. package/src/filters/system-exception.filter.js.map +1 -0
  48. package/src/filters/system-exception.filter.ts +13 -0
  49. package/src/filters/validation-exception.filter.d.ts +8 -0
  50. package/src/filters/validation-exception.filter.js +66 -0
  51. package/src/filters/validation-exception.filter.js.map +1 -0
  52. package/src/filters/validation-exception.filter.ts +24 -0
  53. package/src/http-status-code-to-errors.d.ts +4 -0
  54. package/src/http-status-code-to-errors.js +24 -0
  55. package/src/http-status-code-to-errors.js.map +1 -0
  56. package/src/http-status-code-to-errors.ts +41 -0
  57. package/src/index.d.ts +5 -0
  58. package/src/index.js +24 -0
  59. package/src/index.js.map +1 -0
  60. package/src/index.ts +7 -0
  61. package/src/result.error.d.ts +4 -0
  62. package/src/result.error.js +24 -0
  63. package/src/result.error.js.map +1 -0
  64. package/src/result.error.ts +25 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.enum.js","sourceRoot":"","sources":["error.enum.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAE5C,IAAY,UA4BX;AA5BD,WAAY,UAAU;IAEpB,yCAA2B,CAAA;IAC3B,6CAA+B,CAAA;IAE/B,2CAA6B,CAAA;IAE7B,qCAAuB,CAAA;IAEvB,mDAAqC,CAAA;IACrC,qCAAuB,CAAA;IACvB,uDAAyC,CAAA;IACzC,qCAAuB,CAAA;IACvB,uDAAyC,CAAA;IACzC,+CAAiC,CAAA;IACjC,mCAAqB,CAAA;IACrB,2BAAa,CAAA;IACb,+DAAiD,CAAA;IACjD,2DAA6C,CAAA;IAC7C,6EAA+D,CAAA;IAC/D,qDAAuC,CAAA;IAGvC,6DAA+C,CAAA;IAC/C,iDAAmC,CAAA;IACnC,yCAA2B,CAAA;IAC3B,yDAA2C,CAAA;IAC3C,iDAAmC,CAAA;AACrC,CAAC,EA5BW,UAAU,0BAAV,UAAU,QA4BrB;AAEM,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC9D,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAU,CAAC,CAAC,IAAI,CACxD,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAC9B,EAAE,CAAC,CAAC,CAAC,CAAC;IACP,MAAM,SAAS,GAAG,UAAU,CAAC,kBAA6C,CAAC,CAAC;IAC5E,OAAO,SAAS,IAAI,SAAS,CAAC;AAChC,CAAC,CAAC;AANW,QAAA,uBAAuB,2BAMlC;AAEF,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,sDAA8B,CAAA;IAC9B,8CAAsB,CAAA;IACtB,kDAA0B,CAAA;AAC5B,CAAC,EAJW,oBAAoB,oCAApB,oBAAoB,QAI/B"}
@@ -0,0 +1,45 @@
1
+ import { HttpStatus } from '@nestjs/common';
2
+
3
+ export enum ErrorsEnum {
4
+ // 400 Client Errors
5
+ BAD_REQUEST = 'Bad request', // 400
6
+ INVALID_VALUE = 'Invalid value', // 400 (custom)
7
+
8
+ UNAUTHORIZED = 'Unauthorized', // 401
9
+
10
+ BAD_LOGIN = 'Bad login', // 401 (custom, usually used for unauthorized access with wrong credentials)
11
+
12
+ PAYMENT_REQUIRED = 'Payment required', // 402
13
+ FORBIDDEN = 'Forbidden', // 403
14
+ FORBIDDEN_RESOURCE = 'Forbidden resource', // 403 (custom)
15
+ NOT_FOUND = 'Not found', // 404
16
+ METHOD_NOT_ALLOWED = 'Method not allowed', // 405
17
+ NOT_ACCEPTABLE = 'Not acceptable', // 406
18
+ CONFLICT = 'Conflict', // 409
19
+ GONE = 'Gone', // 410
20
+ UNSUPPORTED_MEDIA_TYPE = 'Unsupported media type', // 415
21
+ UNPROCESSABLE_ENTITY = 'Unprocessable entity', // 422
22
+ UNAVAILABLE_FOR_LEGAL_REASONS = 'Unavailable for legal reasons', // 451
23
+ TOO_MANY_REQUESTS = 'Too many requests', // 429
24
+
25
+ // 500 Server Errors
26
+ INTERNAL_SERVER_ERROR = 'Internal server error', // 500
27
+ NOT_IMPLEMENTED = 'Not implemented', // 501
28
+ BAD_GATEWAY = 'Bad gateway', // 502
29
+ SERVICE_UNAVAILABLE = 'Service unavailable', // 503
30
+ GATEWAY_TIMEOUT = 'Gateway timeout', // 504
31
+ }
32
+
33
+ export const getHttpStatusNameByCode = (code: number): string => {
34
+ const httpStatusEnumName = Object.entries(HttpStatus).find(
35
+ ([, value]) => value === code,
36
+ )?.[0];
37
+ const enumValue = ErrorsEnum[httpStatusEnumName as keyof typeof ErrorsEnum];
38
+ return enumValue ?? 'Unknown';
39
+ };
40
+
41
+ export enum ExceptionContextEnum {
42
+ DATABASE = 'DatabaseException',
43
+ HTTP = 'HttpException',
44
+ SYSTEM = 'SystemException',
45
+ }
@@ -0,0 +1,2 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ export declare function getStatusCodeFromError(error: ClassType<any> | any): any;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStatusCodeFromError = getStatusCodeFromError;
4
+ const class_helper_js_1 = require("@nest-yalc-2/utils/class.helper.js");
5
+ const http_helper_js_1 = require("@nest-yalc-2/utils/http.helper.js");
6
+ const default_error_js_1 = require("./default.error.js");
7
+ function getStatusCodeFromError(error) {
8
+ if (!(0, class_helper_js_1.isClass)(error)) {
9
+ if (error.getStatus) {
10
+ return error.getStatus();
11
+ }
12
+ return null;
13
+ }
14
+ if ((0, default_error_js_1.isDefaultErrorMixinClass)(error)) {
15
+ return error.defaultStatusCode;
16
+ }
17
+ const errorName = error.name;
18
+ return http_helper_js_1.httpExceptionStatusCodes[errorName] || null;
19
+ }
20
+ //# sourceMappingURL=error.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.helper.js","sourceRoot":"","sources":["error.helper.ts"],"names":[],"mappings":";;AASA,wDAwBC;AAhCD,wEAA6D;AAC7D,sEAA6E;AAC7E,yDAA8D;AAM9D,SAAgB,sBAAsB,CAAC,KAA2B;IAIhE,IAAI,CAAC,IAAA,yBAAO,EAAC,KAAK,CAAC,EAAE,CAAC;QACpB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,IAAI,IAAA,2CAAwB,EAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,iBAAiB,CAAC;IACjC,CAAC;IAKD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;IAC7B,OAAO,yCAAwB,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACrD,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ import { isClass } from '@nest-yalc-2/utils/class.helper.js';
3
+ import { httpExceptionStatusCodes } from '@nest-yalc-2/utils/http.helper.js';
4
+ import { isDefaultErrorMixinClass } from './default.error.js';
5
+
6
+ /**
7
+ * Function to convert all HttpException based errors classes to their corresponding status code
8
+ * using a predefined list of status codes
9
+ */
10
+ export function getStatusCodeFromError(error: ClassType<any> | any) {
11
+ /**
12
+ * If it's not a class, check if it has a getStatus method
13
+ */
14
+ if (!isClass(error)) {
15
+ if (error.getStatus) {
16
+ return error.getStatus();
17
+ }
18
+
19
+ return null;
20
+ }
21
+
22
+ /**
23
+ * Check Default error classes
24
+ */
25
+ if (isDefaultErrorMixinClass(error)) {
26
+ return error.defaultStatusCode;
27
+ }
28
+
29
+ /**
30
+ * Check HttpException classes
31
+ */
32
+ const errorName = error.name;
33
+ return httpExceptionStatusCodes[errorName] || null;
34
+ }
@@ -0,0 +1,7 @@
1
+ import { GqlExceptionFilter } from '@nestjs/graphql';
2
+ import * as common from '@nestjs/common';
3
+ export declare class DatabaseExceptionFilter implements GqlExceptionFilter {
4
+ private logger;
5
+ constructor(logger: common.LoggerService);
6
+ catch(error: Error, host: common.ArgumentsHost): Error;
7
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.DatabaseExceptionFilter = void 0;
46
+ const graphql_1 = require("@nestjs/graphql");
47
+ const common = __importStar(require("@nestjs/common"));
48
+ const typeorm_1 = require("typeorm");
49
+ const error_enum_js_1 = require("../error.enum.js");
50
+ let DatabaseExceptionFilter = class DatabaseExceptionFilter {
51
+ constructor(logger) {
52
+ this.logger = logger;
53
+ }
54
+ catch(error, host) {
55
+ const gqlHost = graphql_1.GqlArgumentsHost.create(host);
56
+ gqlHost.getType();
57
+ switch (true) {
58
+ case error instanceof typeorm_1.EntityNotFoundError:
59
+ this.logger.error(error, error_enum_js_1.ExceptionContextEnum.DATABASE);
60
+ error = new common.InternalServerErrorException(error);
61
+ break;
62
+ default:
63
+ this.logger.error(error, error.stack, error_enum_js_1.ExceptionContextEnum.DATABASE);
64
+ break;
65
+ }
66
+ return error;
67
+ }
68
+ };
69
+ exports.DatabaseExceptionFilter = DatabaseExceptionFilter;
70
+ exports.DatabaseExceptionFilter = DatabaseExceptionFilter = __decorate([
71
+ common.Catch(typeorm_1.EntityNotFoundError, typeorm_1.ConnectionNotFoundError),
72
+ __metadata("design:paramtypes", [Object])
73
+ ], DatabaseExceptionFilter);
74
+ //# sourceMappingURL=database-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-exception.filter.js","sourceRoot":"","sources":["database-exception.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAuE;AACvE,uDAAyC;AAEzC,qCAAuE;AACvE,oDAAwD;AAGjD,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAClC,YAAoB,MAA4B;QAA5B,WAAM,GAAN,MAAM,CAAsB;IAAG,CAAC;IAEpD,KAAK,CAAC,KAAY,EAAE,IAA0B;QAC5C,MAAM,OAAO,GAAG,0BAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,CAAC,OAAO,EAAE,CAAC;QAWlB,QAAQ,IAAI,EAAE,CAAC;YAIb,KAAK,KAAK,YAAY,6BAAmB;gBACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,oCAAoB,CAAC,QAAQ,CAAC,CAAC;gBACxD,KAAK,GAAG,IAAI,MAAM,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC;gBAEvD,MAAM;YAER;gBACE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,oCAAoB,CAAC,QAAQ,CAAC,CAAC;gBAErE,MAAM;QACV,CAAC;QAGD,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AAnCY,0DAAuB;kCAAvB,uBAAuB;IADnC,MAAM,CAAC,KAAK,CAAC,6BAAmB,EAAE,iCAAuB,CAAC;;GAC9C,uBAAuB,CAmCnC"}
@@ -0,0 +1,43 @@
1
+ import { GqlExceptionFilter, GqlArgumentsHost } from '@nestjs/graphql';
2
+ import * as common from '@nestjs/common';
3
+ // We can import more errors from the typeorm/error folder if necessary, nothing is exported though, so use explicit paths.
4
+ import { EntityNotFoundError, ConnectionNotFoundError } from 'typeorm';
5
+ import { ExceptionContextEnum } from '../error.enum.js';
6
+
7
+ @common.Catch(EntityNotFoundError, ConnectionNotFoundError)
8
+ export class DatabaseExceptionFilter implements GqlExceptionFilter {
9
+ constructor(private logger: common.LoggerService) {}
10
+
11
+ catch(error: Error, host: common.ArgumentsHost) {
12
+ const gqlHost = GqlArgumentsHost.create(host);
13
+ gqlHost.getType();
14
+
15
+ // Normally transactions are for performance monitoring,
16
+ // Op and Name reflect which operation and function we are running
17
+ // Could not get issue tracking working without, using exception filter as op.
18
+ // const transaction = Sentry.startTransaction({
19
+ // op: 'DatabaseExceptionFilter', // operation (encode)
20
+ // name: 'Caught Error', // name (parseAvatarImage)
21
+ // });
22
+
23
+ // TODO: Validate when monitoring is in place if we need an eventEmitter here instead of log
24
+ switch (true) {
25
+ // Re-throw a new 500 HTTP-friendly error
26
+ // Add more TypeORM errors here, because there's no base Error class
27
+ // @url: https://github.com/typeorm/typeorm/issues/3479
28
+ case error instanceof EntityNotFoundError:
29
+ this.logger.error(error, ExceptionContextEnum.DATABASE);
30
+ error = new common.InternalServerErrorException(error);
31
+ // Sentry.captureException(error);
32
+ break;
33
+ // Log critically any other error, because those are not expected normally
34
+ default:
35
+ this.logger.error(error, error.stack, ExceptionContextEnum.DATABASE);
36
+ // Sentry.captureException(error);
37
+ break;
38
+ }
39
+ // transaction.finish();
40
+
41
+ return error;
42
+ }
43
+ }
@@ -0,0 +1,16 @@
1
+ import { GqlExceptionFilter } from '@nestjs/graphql';
2
+ import * as common from '@nestjs/common';
3
+ import { DefaultErrorMixin, MissingArgumentsError } from '@nest-yalc-2/errors';
4
+ import { FastifyReply as FResponse } from 'fastify';
5
+ import { GqlError } from '@nest-yalc-2/graphql/plugins/gql.error.js';
6
+ import { BaseExceptionFilter } from '@nestjs/core';
7
+ import { type ImprovedLoggerService } from '@nest-yalc-2/logger/logger-abstract.service.js';
8
+ type HttpErrorType = common.HttpException | MissingArgumentsError | GqlError | DefaultErrorMixin;
9
+ export declare class HttpExceptionFilter extends BaseExceptionFilter implements GqlExceptionFilter, common.ExceptionFilter {
10
+ protected logger: ImprovedLoggerService;
11
+ constructor(logger: ImprovedLoggerService, applicationRef?: common.HttpServer);
12
+ catch(error: Error | HttpErrorType, host: common.ArgumentsHost, { sendResponse }?: {
13
+ sendResponse: boolean;
14
+ }): Error | import("@nest-yalc-2/errors").IAbstractDefaultError | FResponse<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
15
+ }
16
+ export {};
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.HttpExceptionFilter = void 0;
46
+ const common = __importStar(require("@nestjs/common"));
47
+ const errors_1 = require("@nest-yalc-2/errors");
48
+ const entity_error_js_1 = require("@nest-yalc-2/crud-gen/entity.error.js");
49
+ const gql_error_js_1 = require("@nest-yalc-2/graphql/plugins/gql.error.js");
50
+ const core_1 = require("@nestjs/core");
51
+ const event_helper_js_1 = require("../../../event-manager/src/event.helper.js");
52
+ const logger_enum_js_1 = require("@nest-yalc-2/logger/logger.enum.js");
53
+ let HttpExceptionFilter = class HttpExceptionFilter extends core_1.BaseExceptionFilter {
54
+ constructor(logger, applicationRef) {
55
+ super(applicationRef);
56
+ this.logger = logger;
57
+ }
58
+ catch(error, host, { sendResponse } = { sendResponse: true }) {
59
+ try {
60
+ const isHttpError = this.isHttpError(error) || error instanceof common.HttpException;
61
+ switch (true) {
62
+ case error instanceof errors_1.MissingArgumentsError:
63
+ this.logger.log(error.message, {
64
+ stack: error.stack,
65
+ });
66
+ break;
67
+ case (0, errors_1.isDefaultErrorMixin)(error):
68
+ break;
69
+ case (0, entity_error_js_1.isEntityError)(error):
70
+ {
71
+ const entityError = error;
72
+ this.logger.error(entityError.originalError?.message
73
+ ? entityError.originalError.message
74
+ : error, entityError.originalError?.stack, {
75
+ stack: entityError.originalError?.stack,
76
+ data: {
77
+ response: entityError.getResponse(),
78
+ name: entityError.name,
79
+ cause: (0, errors_1.formatCause)(entityError.cause),
80
+ },
81
+ });
82
+ }
83
+ break;
84
+ case isHttpError:
85
+ {
86
+ const httpError = error;
87
+ const logLevel = (0, event_helper_js_1.getLogLevelByStatus)(httpError.getStatus());
88
+ if (logLevel === logger_enum_js_1.LogLevelEnum.ERROR) {
89
+ this.logger[logLevel](error.message, error.stack, {
90
+ stack: httpError.stack,
91
+ data: {
92
+ response: httpError.getResponse(),
93
+ name: error.name,
94
+ cause: (0, errors_1.formatCause)(error.cause),
95
+ },
96
+ });
97
+ }
98
+ else {
99
+ this.logger[logLevel](error.message, {
100
+ stack: error.stack,
101
+ data: {
102
+ response: httpError.getResponse(),
103
+ name: error.name,
104
+ cause: (0, errors_1.formatCause)(error.cause),
105
+ },
106
+ });
107
+ }
108
+ }
109
+ break;
110
+ case error instanceof gql_error_js_1.GqlError:
111
+ this.logger.error(error.systemMessage ?? error.message);
112
+ break;
113
+ default:
114
+ this.logger.error(error.message, error.stack, {
115
+ stack: error.stack,
116
+ data: {
117
+ cause: (0, errors_1.formatCause)(error.cause),
118
+ name: error.name,
119
+ },
120
+ });
121
+ break;
122
+ }
123
+ if (host.getType() === 'http') {
124
+ if (sendResponse) {
125
+ const ctx = host.switchToHttp();
126
+ const response = ctx.getResponse();
127
+ let status = common.HttpStatus.INTERNAL_SERVER_ERROR;
128
+ if (isHttpError)
129
+ status = error.getStatus();
130
+ return response.status(status).send(error.message);
131
+ }
132
+ }
133
+ }
134
+ catch (e) {
135
+ console.error(e);
136
+ }
137
+ return error;
138
+ }
139
+ };
140
+ exports.HttpExceptionFilter = HttpExceptionFilter;
141
+ exports.HttpExceptionFilter = HttpExceptionFilter = __decorate([
142
+ common.Catch(common.HttpException, errors_1.MissingArgumentsError, gql_error_js_1.GqlError, errors_1.DefaultErrorMixin),
143
+ __metadata("design:paramtypes", [Object, Object])
144
+ ], HttpExceptionFilter);
145
+ //# sourceMappingURL=http-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-exception.filter.js","sourceRoot":"","sources":["http-exception.filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ import { GqlExceptionFilter } from '@nestjs/graphql';
2
+ import * as common from '@nestjs/common';
3
+ import {
4
+ DefaultErrorMixin,
5
+ MissingArgumentsError,
6
+ isDefaultErrorMixin,
7
+ formatCause,
8
+ } from '@nest-yalc-2/errors';
9
+ import {
10
+ EntityError,
11
+ isEntityError,
12
+ } from '@nest-yalc-2/crud-gen/entity.error.js';
13
+ import { FastifyReply as FResponse } from 'fastify';
14
+ import { GqlError } from '@nest-yalc-2/graphql/plugins/gql.error.js';
15
+ import { BaseExceptionFilter } from '@nestjs/core';
16
+ import { getLogLevelByStatus } from '../../../event-manager/src/event.helper.js';
17
+ import { LogLevelEnum } from '@nest-yalc-2/logger/logger.enum.js';
18
+ import { type ImprovedLoggerService } from '@nest-yalc-2/logger/logger-abstract.service.js';
19
+
20
+ type HttpErrorType =
21
+ common.HttpException | MissingArgumentsError | GqlError | DefaultErrorMixin;
22
+ @common.Catch(
23
+ common.HttpException,
24
+ MissingArgumentsError,
25
+ GqlError,
26
+ DefaultErrorMixin,
27
+ )
28
+ export class HttpExceptionFilter
29
+ extends BaseExceptionFilter
30
+ implements GqlExceptionFilter, common.ExceptionFilter
31
+ {
32
+ constructor(
33
+ protected logger: ImprovedLoggerService,
34
+ applicationRef?: common.HttpServer,
35
+ ) {
36
+ super(applicationRef);
37
+ }
38
+
39
+ catch(
40
+ error: Error | HttpErrorType,
41
+ host: common.ArgumentsHost,
42
+ { sendResponse }: { sendResponse: boolean } = { sendResponse: true },
43
+ ) {
44
+ try {
45
+ const isHttpError =
46
+ this.isHttpError(error) || error instanceof common.HttpException;
47
+ // TODO: Validate when monitoring is in place if we need an eventEmitter here instead of log
48
+ switch (true) {
49
+ // Base logging for normal operation execution errors
50
+ case error instanceof MissingArgumentsError:
51
+ this.logger.log(error.message, {
52
+ stack: error.stack,
53
+ });
54
+ break;
55
+
56
+ case isDefaultErrorMixin(error):
57
+ // no need to log, DefaultErrorMixin already logs
58
+ break;
59
+
60
+ /**
61
+ * Log original error message (for now only if is an EntityError)
62
+ * @todo refactor with the default error mixin
63
+ */
64
+ case isEntityError(error):
65
+ {
66
+ const entityError = error as EntityError;
67
+ this.logger.error(
68
+ entityError.originalError?.message
69
+ ? entityError.originalError.message
70
+ : error,
71
+ entityError.originalError?.stack,
72
+ {
73
+ stack: entityError.originalError?.stack,
74
+ data: {
75
+ response: entityError.getResponse(),
76
+ name: entityError.name,
77
+ cause: formatCause(entityError.cause),
78
+ },
79
+ },
80
+ );
81
+ }
82
+ break;
83
+
84
+ case isHttpError:
85
+ {
86
+ const httpError = error as common.HttpException;
87
+ const logLevel = getLogLevelByStatus(httpError.getStatus());
88
+
89
+ if (logLevel === LogLevelEnum.ERROR) {
90
+ this.logger[logLevel](error.message, error.stack, {
91
+ stack: httpError.stack,
92
+ data: {
93
+ response: httpError.getResponse(),
94
+ name: error.name,
95
+ cause: formatCause(error.cause),
96
+ },
97
+ });
98
+ } else {
99
+ this.logger[logLevel](error.message, {
100
+ stack: error.stack,
101
+ data: {
102
+ response: httpError.getResponse(),
103
+ name: error.name,
104
+ cause: formatCause(error.cause),
105
+ },
106
+ });
107
+ }
108
+ }
109
+ break;
110
+
111
+ case error instanceof GqlError:
112
+ this.logger.error((<GqlError>error).systemMessage ?? error.message);
113
+ break;
114
+
115
+ // Log critically any other error, as those are not expected
116
+ default:
117
+ this.logger.error(error.message, error.stack, {
118
+ stack: error.stack,
119
+ data: {
120
+ cause: formatCause(error.cause),
121
+ name: error.name,
122
+ },
123
+ });
124
+ break;
125
+ }
126
+
127
+ if (host.getType() === 'http') {
128
+ if (sendResponse) {
129
+ const ctx = host.switchToHttp();
130
+ const response = ctx.getResponse<FResponse>();
131
+ let status = common.HttpStatus.INTERNAL_SERVER_ERROR;
132
+ if (isHttpError) status = (error as common.HttpException).getStatus();
133
+ return response.status(status).send(error.message);
134
+ }
135
+ }
136
+ } catch (e) {
137
+ // eslint-disable-next-line no-console
138
+ console.error(e); // if there's an error with the logger itself
139
+ }
140
+
141
+ return error;
142
+ }
143
+ }
@@ -0,0 +1 @@
1
+ export { SystemExceptionFilter } from './system-exception.filter.js';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SystemExceptionFilter = void 0;
4
+ var system_exception_filter_js_1 = require("./system-exception.filter.js");
5
+ Object.defineProperty(exports, "SystemExceptionFilter", { enumerable: true, get: function () { return system_exception_filter_js_1.SystemExceptionFilter; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAKA,2EAAqE;AAA5D,mIAAA,qBAAqB,OAAA"}
@@ -0,0 +1,6 @@
1
+ /* istanbul ignore file */
2
+
3
+ // export { HttpExceptionFilter } from './http-exception.filter.js';
4
+ // export { DatabaseExceptionFilter } from './database-exception.filter.js';
5
+ // export { ValidationExceptionFilter } from './validation-exception.filter.js';
6
+ export { SystemExceptionFilter } from './system-exception.filter.js';
@@ -0,0 +1,7 @@
1
+ import { ExceptionFilter } from '@nestjs/common';
2
+ import type { LoggerService } from '@nestjs/common';
3
+ export declare class SystemExceptionFilter implements ExceptionFilter {
4
+ private logger;
5
+ constructor(logger: LoggerService);
6
+ catch(error: Error): Error;
7
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SystemExceptionFilter = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const error_enum_js_1 = require("../error.enum.js");
15
+ let SystemExceptionFilter = class SystemExceptionFilter {
16
+ constructor(logger) {
17
+ this.logger = logger;
18
+ }
19
+ catch(error) {
20
+ this.logger.error(error, error.stack, error_enum_js_1.ExceptionContextEnum.SYSTEM);
21
+ return error;
22
+ }
23
+ };
24
+ exports.SystemExceptionFilter = SystemExceptionFilter;
25
+ exports.SystemExceptionFilter = SystemExceptionFilter = __decorate([
26
+ (0, common_1.Catch)(TypeError, SyntaxError, RangeError, EvalError, ReferenceError),
27
+ __metadata("design:paramtypes", [Object])
28
+ ], SystemExceptionFilter);
29
+ //# sourceMappingURL=system-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-exception.filter.js","sourceRoot":"","sources":["system-exception.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwD;AAExD,oDAAwD;AAGjD,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,YAAoB,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAE7C,KAAK,CAAC,KAAY;QAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,oCAAoB,CAAC,MAAM,CAAC,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AAPY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,cAAK,EAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC;;GACxD,qBAAqB,CAOjC"}
@@ -0,0 +1,13 @@
1
+ import { Catch, ExceptionFilter } from '@nestjs/common';
2
+ import type { LoggerService } from '@nestjs/common';
3
+ import { ExceptionContextEnum } from '../error.enum.js';
4
+
5
+ @Catch(TypeError, SyntaxError, RangeError, EvalError, ReferenceError)
6
+ export class SystemExceptionFilter implements ExceptionFilter {
7
+ constructor(private logger: LoggerService) {}
8
+
9
+ catch(error: Error) {
10
+ this.logger.error(error, error.stack, ExceptionContextEnum.SYSTEM);
11
+ return error;
12
+ }
13
+ }
@@ -0,0 +1,8 @@
1
+ import * as common from '@nestjs/common';
2
+ import { GqlExceptionFilter } from '@nestjs/graphql';
3
+ import { InputValidationError } from '../index.js';
4
+ export declare class ValidationExceptionFilter implements GqlExceptionFilter {
5
+ private logger;
6
+ constructor(logger: common.LoggerService);
7
+ catch(error: Error): InputValidationError;
8
+ }