@eventista/ticketing-common 1.0.1030 → 1.0.1034-beta.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/exception/exception.filter.d.ts +3 -0
- package/dist/exception/exception.filter.js +59 -0
- package/dist/exception/exception.filter.js.map +1 -1
- package/dist/exception/unified-exception.filter.d.ts +9 -0
- package/dist/exception/unified-exception.filter.js +152 -0
- package/dist/exception/unified-exception.filter.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/logger/custom.logger.d.ts +5 -1
- package/dist/logger/custom.logger.js +27 -0
- package/dist/logger/custom.logger.js.map +1 -1
- package/dist/logger/examples/logger-sentry.example.d.ts +32 -0
- package/dist/logger/examples/logger-sentry.example.js +211 -0
- package/dist/logger/examples/logger-sentry.example.js.map +1 -0
- package/dist/sentry/decorators/index.d.ts +2 -0
- package/dist/sentry/decorators/index.js +19 -0
- package/dist/sentry/decorators/index.js.map +1 -0
- package/dist/sentry/decorators/sentry-capture.decorator.d.ts +9 -0
- package/dist/sentry/decorators/sentry-capture.decorator.js +13 -0
- package/dist/sentry/decorators/sentry-capture.decorator.js.map +1 -0
- package/dist/sentry/decorators/sentry-trace.decorator.d.ts +9 -0
- package/dist/sentry/decorators/sentry-trace.decorator.js +8 -0
- package/dist/sentry/decorators/sentry-trace.decorator.js.map +1 -0
- package/dist/sentry/examples/optimized-usage.example.d.ts +33 -0
- package/dist/sentry/examples/optimized-usage.example.js +300 -0
- package/dist/sentry/examples/optimized-usage.example.js.map +1 -0
- package/dist/sentry/examples/sentry-usage.example.d.ts +39 -0
- package/dist/sentry/examples/sentry-usage.example.js +262 -0
- package/dist/sentry/examples/sentry-usage.example.js.map +1 -0
- package/dist/sentry/index.d.ts +10 -0
- package/dist/sentry/index.js +27 -0
- package/dist/sentry/index.js.map +1 -0
- package/dist/sentry/interceptors/index.d.ts +2 -0
- package/dist/sentry/interceptors/index.js +19 -0
- package/dist/sentry/interceptors/index.js.map +1 -0
- package/dist/sentry/interceptors/sentry-capture.interceptor.d.ts +8 -0
- package/dist/sentry/interceptors/sentry-capture.interceptor.js +80 -0
- package/dist/sentry/interceptors/sentry-capture.interceptor.js.map +1 -0
- package/dist/sentry/interceptors/sentry-trace.interceptor.d.ts +8 -0
- package/dist/sentry/interceptors/sentry-trace.interceptor.js +56 -0
- package/dist/sentry/interceptors/sentry-trace.interceptor.js.map +1 -0
- package/dist/sentry/sentry-logger.helper.d.ts +22 -0
- package/dist/sentry/sentry-logger.helper.js +153 -0
- package/dist/sentry/sentry-logger.helper.js.map +1 -0
- package/dist/sentry/sentry-safe.module.d.ts +11 -0
- package/dist/sentry/sentry-safe.module.js +82 -0
- package/dist/sentry/sentry-safe.module.js.map +1 -0
- package/dist/sentry/sentry.advanced-config.d.ts +35 -0
- package/dist/sentry/sentry.advanced-config.js +99 -0
- package/dist/sentry/sentry.advanced-config.js.map +1 -0
- package/dist/sentry/sentry.config.d.ts +20 -0
- package/dist/sentry/sentry.config.js +20 -0
- package/dist/sentry/sentry.config.js.map +1 -0
- package/dist/sentry/sentry.filter.d.ts +12 -0
- package/dist/sentry/sentry.filter.js +139 -0
- package/dist/sentry/sentry.filter.js.map +1 -0
- package/dist/sentry/sentry.interceptor.d.ts +9 -0
- package/dist/sentry/sentry.interceptor.js +80 -0
- package/dist/sentry/sentry.interceptor.js.map +1 -0
- package/dist/sentry/sentry.module.d.ts +2 -0
- package/dist/sentry/sentry.module.js +45 -0
- package/dist/sentry/sentry.module.js.map +1 -0
- package/dist/sentry/sentry.service.d.ts +56 -0
- package/dist/sentry/sentry.service.js +255 -0
- package/dist/sentry/sentry.service.js.map +1 -0
- package/dist/sentry/types/index.d.ts +30 -0
- package/dist/sentry/types/index.js +3 -0
- package/dist/sentry/types/index.js.map +1 -0
- package/dist/shared.module.js +3 -0
- package/dist/shared.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -2
|
@@ -2,5 +2,8 @@ import { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
|
|
|
2
2
|
export declare class GlobalExceptionFilter implements ExceptionFilter {
|
|
3
3
|
private readonly logger;
|
|
4
4
|
catch(exception: any, host: ArgumentsHost): any;
|
|
5
|
+
private captureToSentry;
|
|
6
|
+
private sanitizeHeaders;
|
|
7
|
+
private sanitizeBody;
|
|
5
8
|
private logError;
|
|
6
9
|
}
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.GlobalExceptionFilter = void 0;
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
12
|
const custom_logger_1 = require("../logger/custom.logger");
|
|
13
|
+
const sentry_logger_helper_1 = require("../sentry/sentry-logger.helper");
|
|
13
14
|
let GlobalExceptionFilter = GlobalExceptionFilter_1 = class GlobalExceptionFilter {
|
|
14
15
|
constructor() {
|
|
15
16
|
this.logger = new custom_logger_1.CustomLogger(GlobalExceptionFilter_1.name);
|
|
@@ -21,6 +22,9 @@ let GlobalExceptionFilter = GlobalExceptionFilter_1 = class GlobalExceptionFilte
|
|
|
21
22
|
const status = exception instanceof common_1.HttpException
|
|
22
23
|
? exception.getStatus()
|
|
23
24
|
: common_1.HttpStatus.INTERNAL_SERVER_ERROR;
|
|
25
|
+
if (status >= 500 || !(exception instanceof common_1.HttpException)) {
|
|
26
|
+
this.captureToSentry(exception, request, status);
|
|
27
|
+
}
|
|
24
28
|
if (status === common_1.HttpStatus.BAD_REQUEST && exception instanceof common_1.HttpException) {
|
|
25
29
|
const exceptionResponse = exception.getResponse();
|
|
26
30
|
if (exceptionResponse.message === 'Validation failed' && exceptionResponse.errors) {
|
|
@@ -58,6 +62,61 @@ let GlobalExceptionFilter = GlobalExceptionFilter_1 = class GlobalExceptionFilte
|
|
|
58
62
|
this.logError(exception, request);
|
|
59
63
|
response.status(status).send(errorResponse);
|
|
60
64
|
}
|
|
65
|
+
captureToSentry(exception, request, status) {
|
|
66
|
+
try {
|
|
67
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureException(exception, `HTTP ${status} Error: ${exception.message}`, 'UnifiedExceptionFilter', {
|
|
68
|
+
enabled: true,
|
|
69
|
+
rateLimitPerMinute: 60,
|
|
70
|
+
});
|
|
71
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureMessage(`Unhandled exception in ${request.method} ${request.url}`, 'error', 'UnifiedExceptionFilter', {
|
|
72
|
+
exception: {
|
|
73
|
+
name: exception.name,
|
|
74
|
+
message: exception.message,
|
|
75
|
+
stack: exception.stack,
|
|
76
|
+
},
|
|
77
|
+
request: {
|
|
78
|
+
method: request.method,
|
|
79
|
+
url: request.url,
|
|
80
|
+
headers: this.sanitizeHeaders(request.headers),
|
|
81
|
+
query: request.query,
|
|
82
|
+
body: this.sanitizeBody(request.body),
|
|
83
|
+
params: request.params,
|
|
84
|
+
},
|
|
85
|
+
response: {
|
|
86
|
+
statusCode: status,
|
|
87
|
+
},
|
|
88
|
+
}, {
|
|
89
|
+
enabled: true,
|
|
90
|
+
sensitiveFields: ['password', 'token', 'authorization', 'cookie'],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('Failed to capture exception to Sentry:', error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
sanitizeHeaders(headers) {
|
|
98
|
+
const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key', 'x-auth-token'];
|
|
99
|
+
const sanitized = { ...headers };
|
|
100
|
+
for (const header of sensitiveHeaders) {
|
|
101
|
+
if (header in sanitized) {
|
|
102
|
+
sanitized[header] = '[REDACTED]';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return sanitized;
|
|
106
|
+
}
|
|
107
|
+
sanitizeBody(body) {
|
|
108
|
+
if (!body || typeof body !== 'object') {
|
|
109
|
+
return body;
|
|
110
|
+
}
|
|
111
|
+
const sensitiveFields = ['password', 'token', 'authorization', 'secret', 'key', 'credential'];
|
|
112
|
+
const sanitized = { ...body };
|
|
113
|
+
for (const field of sensitiveFields) {
|
|
114
|
+
if (field in sanitized) {
|
|
115
|
+
sanitized[field] = '[REDACTED]';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return sanitized;
|
|
119
|
+
}
|
|
61
120
|
logError(exception, request) {
|
|
62
121
|
const status = exception instanceof common_1.HttpException
|
|
63
122
|
? exception.getStatus()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exception.filter.js","sourceRoot":"","sources":["../../src/exception/exception.filter.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAMwB;AACxB,2DAAuD;
|
|
1
|
+
{"version":3,"file":"exception.filter.js","sourceRoot":"","sources":["../../src/exception/exception.filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
|
|
2
|
+
export declare class UnifiedExceptionFilter implements ExceptionFilter {
|
|
3
|
+
private readonly logger;
|
|
4
|
+
catch(exception: any, host: ArgumentsHost): any;
|
|
5
|
+
private captureToSentry;
|
|
6
|
+
private logError;
|
|
7
|
+
private sanitizeHeaders;
|
|
8
|
+
private sanitizeBody;
|
|
9
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
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 UnifiedExceptionFilter_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.UnifiedExceptionFilter = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const custom_logger_1 = require("../logger/custom.logger");
|
|
13
|
+
const sentry_logger_helper_1 = require("../sentry/sentry-logger.helper");
|
|
14
|
+
let UnifiedExceptionFilter = UnifiedExceptionFilter_1 = class UnifiedExceptionFilter {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.logger = new custom_logger_1.CustomLogger(UnifiedExceptionFilter_1.name);
|
|
17
|
+
}
|
|
18
|
+
catch(exception, host) {
|
|
19
|
+
const ctx = host.switchToHttp();
|
|
20
|
+
const response = ctx.getResponse();
|
|
21
|
+
const request = ctx.getRequest();
|
|
22
|
+
const status = exception instanceof common_1.HttpException
|
|
23
|
+
? exception.getStatus()
|
|
24
|
+
: common_1.HttpStatus.INTERNAL_SERVER_ERROR;
|
|
25
|
+
if (status >= 500 || !(exception instanceof common_1.HttpException)) {
|
|
26
|
+
this.captureToSentry(exception, request, status);
|
|
27
|
+
}
|
|
28
|
+
if (status === common_1.HttpStatus.BAD_REQUEST && exception instanceof common_1.HttpException) {
|
|
29
|
+
const exceptionResponse = exception.getResponse();
|
|
30
|
+
if (exceptionResponse.message === 'Validation failed' && exceptionResponse.errors) {
|
|
31
|
+
const errorResponse = {
|
|
32
|
+
statusCode: status,
|
|
33
|
+
message: exceptionResponse.message,
|
|
34
|
+
errors: exceptionResponse.errors,
|
|
35
|
+
path: request.url,
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
data: exception instanceof common_1.HttpException ? exception.getResponse()['data'] : null,
|
|
38
|
+
};
|
|
39
|
+
return response.status(status).json(errorResponse);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (exception instanceof common_1.HttpException) {
|
|
43
|
+
const exceptionResponse = exception.getResponse();
|
|
44
|
+
const errorResponse = {
|
|
45
|
+
statusCode: status,
|
|
46
|
+
errorCode: exceptionResponse.code || status,
|
|
47
|
+
message: exception.message,
|
|
48
|
+
path: request.url,
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
data: exception instanceof common_1.HttpException ? exception.getResponse()['data'] : null,
|
|
51
|
+
};
|
|
52
|
+
return response.status(status).json(errorResponse);
|
|
53
|
+
}
|
|
54
|
+
const errorResponse = {
|
|
55
|
+
statusCode: status,
|
|
56
|
+
errorCode: status,
|
|
57
|
+
message: 'Hệ thống đang bận, vui lòng thử lại sau.',
|
|
58
|
+
path: request.url,
|
|
59
|
+
timestamp: new Date().toISOString(),
|
|
60
|
+
data: null,
|
|
61
|
+
};
|
|
62
|
+
this.logError(exception, request, status);
|
|
63
|
+
response.status(status).json(errorResponse);
|
|
64
|
+
}
|
|
65
|
+
captureToSentry(exception, request, status) {
|
|
66
|
+
try {
|
|
67
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureException(exception, `HTTP ${status} Error: ${exception.message}`, 'UnifiedExceptionFilter', {
|
|
68
|
+
enabled: true,
|
|
69
|
+
rateLimitPerMinute: 60,
|
|
70
|
+
});
|
|
71
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureMessage(`Unhandled exception in ${request.method} ${request.url}`, 'error', 'UnifiedExceptionFilter', {
|
|
72
|
+
exception: {
|
|
73
|
+
name: exception.name,
|
|
74
|
+
message: exception.message,
|
|
75
|
+
stack: exception.stack,
|
|
76
|
+
},
|
|
77
|
+
request: {
|
|
78
|
+
method: request.method,
|
|
79
|
+
url: request.url,
|
|
80
|
+
headers: this.sanitizeHeaders(request.headers),
|
|
81
|
+
query: request.query,
|
|
82
|
+
body: this.sanitizeBody(request.body),
|
|
83
|
+
params: request.params,
|
|
84
|
+
},
|
|
85
|
+
response: {
|
|
86
|
+
statusCode: status,
|
|
87
|
+
},
|
|
88
|
+
}, {
|
|
89
|
+
enabled: true,
|
|
90
|
+
sensitiveFields: ['password', 'token', 'authorization', 'cookie'],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('Failed to capture exception to Sentry:', error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
logError(exception, request, status) {
|
|
98
|
+
const errorInfo = {
|
|
99
|
+
exception: {
|
|
100
|
+
name: exception.name,
|
|
101
|
+
message: exception.message,
|
|
102
|
+
stack: exception.stack,
|
|
103
|
+
},
|
|
104
|
+
request: {
|
|
105
|
+
method: request.method,
|
|
106
|
+
url: request.url,
|
|
107
|
+
headers: this.sanitizeHeaders(request.headers),
|
|
108
|
+
query: request.query,
|
|
109
|
+
body: this.sanitizeBody(request.body),
|
|
110
|
+
params: request.params,
|
|
111
|
+
},
|
|
112
|
+
response: {
|
|
113
|
+
statusCode: status,
|
|
114
|
+
},
|
|
115
|
+
timestamp: new Date().toISOString(),
|
|
116
|
+
};
|
|
117
|
+
if (status >= 500) {
|
|
118
|
+
this.logger.error(`[${request.method}] ${request.url} - Status: ${status}`, errorInfo);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
this.logger.warn(`[${request.method}] ${request.url} - Status: ${status}`, errorInfo);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
sanitizeHeaders(headers) {
|
|
125
|
+
const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key', 'x-auth-token'];
|
|
126
|
+
const sanitized = { ...headers };
|
|
127
|
+
for (const header of sensitiveHeaders) {
|
|
128
|
+
if (header in sanitized) {
|
|
129
|
+
sanitized[header] = '[REDACTED]';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return sanitized;
|
|
133
|
+
}
|
|
134
|
+
sanitizeBody(body) {
|
|
135
|
+
if (!body || typeof body !== 'object') {
|
|
136
|
+
return body;
|
|
137
|
+
}
|
|
138
|
+
const sensitiveFields = ['password', 'token', 'authorization', 'secret', 'key', 'credential'];
|
|
139
|
+
const sanitized = { ...body };
|
|
140
|
+
for (const field of sensitiveFields) {
|
|
141
|
+
if (field in sanitized) {
|
|
142
|
+
sanitized[field] = '[REDACTED]';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return sanitized;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
exports.UnifiedExceptionFilter = UnifiedExceptionFilter;
|
|
149
|
+
exports.UnifiedExceptionFilter = UnifiedExceptionFilter = UnifiedExceptionFilter_1 = __decorate([
|
|
150
|
+
(0, common_1.Catch)()
|
|
151
|
+
], UnifiedExceptionFilter);
|
|
152
|
+
//# sourceMappingURL=unified-exception.filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified-exception.filter.js","sourceRoot":"","sources":["../../src/exception/unified-exception.filter.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAMwB;AACxB,2DAAuD;AACvD,yEAAoE;AAG7D,IAAM,sBAAsB,8BAA5B,MAAM,sBAAsB;IAA5B;QACY,WAAM,GAAG,IAAI,4BAAY,CAAC,wBAAsB,CAAC,IAAI,CAAC,CAAC;IA4K1E,CAAC;IA1KC,KAAK,CAAC,SAAc,EAAE,IAAmB;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAEjC,MAAM,MAAM,GACV,SAAS,YAAY,sBAAa;YAChC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE;YACvB,CAAC,CAAC,mBAAU,CAAC,qBAAqB,CAAC;QAGvC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,SAAS,YAAY,sBAAa,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;QAGD,IAAI,MAAM,KAAK,mBAAU,CAAC,WAAW,IAAI,SAAS,YAAY,sBAAa,EAAE,CAAC;YAC5E,MAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,EAAS,CAAC;YAEzD,IAAI,iBAAiB,CAAC,OAAO,KAAK,mBAAmB,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;gBAClF,MAAM,aAAa,GAAG;oBACpB,UAAU,EAAE,MAAM;oBAClB,OAAO,EAAE,iBAAiB,CAAC,OAAO;oBAClC,MAAM,EAAE,iBAAiB,CAAC,MAAM;oBAChC,IAAI,EAAE,OAAO,CAAC,GAAG;oBACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,IAAI,EAAE,SAAS,YAAY,sBAAa,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;iBAClF,CAAC;gBAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAGD,IAAI,SAAS,YAAY,sBAAa,EAAE,CAAC;YACvC,MAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,EAAS,CAAC;YAEzD,MAAM,aAAa,GAAG;gBACpB,UAAU,EAAE,MAAM;gBAClB,SAAS,EAAE,iBAAiB,CAAC,IAAI,IAAI,MAAM;gBAC3C,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,IAAI,EAAE,OAAO,CAAC,GAAG;gBACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,IAAI,EAAE,SAAS,YAAY,sBAAa,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;aAClF,CAAC;YAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrD,CAAC;QAGD,MAAM,aAAa,GAAG;YACpB,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,0CAA0C;YACnD,IAAI,EAAE,OAAO,CAAC,GAAG;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI,EAAE,IAAI;SACX,CAAC;QAGF,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1C,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAEO,eAAe,CAAC,SAAc,EAAE,OAAY,EAAE,MAAc;QAClE,IAAI,CAAC;YAEH,yCAAkB,CAAC,gBAAgB,CACjC,SAAS,EACT,QAAQ,MAAM,WAAW,SAAS,CAAC,OAAO,EAAE,EAC5C,wBAAwB,EACxB;gBACE,OAAO,EAAE,IAAI;gBACb,kBAAkB,EAAE,EAAE;aACvB,CACF,CAAC;YAGF,yCAAkB,CAAC,cAAc,CAC/B,0BAA0B,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,EACzD,OAAO,EACP,wBAAwB,EACxB;gBACE,SAAS,EAAE;oBACT,IAAI,EAAE,SAAS,CAAC,IAAI;oBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;iBACvB;gBACD,OAAO,EAAE;oBACP,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;oBAC9C,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;oBACrC,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB;gBACD,QAAQ,EAAE;oBACR,UAAU,EAAE,MAAM;iBACnB;aACF,EACD;gBACE,OAAO,EAAE,IAAI;gBACb,eAAe,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC;aAClE,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,SAAc,EAAE,OAAY,EAAE,MAAc;QAC3D,MAAM,SAAS,GAAG;YAChB,SAAS,EAAE;gBACT,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;aACvB;YACD,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;gBAC9C,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrC,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;YACD,QAAQ,EAAE;gBACR,UAAU,EAAE,MAAM;aACnB;YACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAGF,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,GAAG,cAAc,MAAM,EAAE,EAAE,SAAS,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,GAAG,cAAc,MAAM,EAAE,EAAE,SAAS,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,OAA4B;QAClD,MAAM,gBAAgB,GAAG,CAAC,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAClF,MAAM,SAAS,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAEjC,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;YACtC,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,SAAS,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,YAAY,CAAC,IAAS;QAC5B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QAE9B,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;gBACvB,SAAS,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC;YAClC,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAA;AA7KY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,cAAK,GAAE;GACK,sBAAsB,CA6KlC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './database';
|
|
2
2
|
export * from './exception/exception.filter';
|
|
3
|
+
export * from './exception/unified-exception.filter';
|
|
3
4
|
export * from './generic-repository';
|
|
4
5
|
export * from './logger';
|
|
5
6
|
export * from './pipes/custom-validation.pipe';
|
|
@@ -10,4 +11,5 @@ export * from './schemas/schema.module';
|
|
|
10
11
|
export * from './cluster/index';
|
|
11
12
|
export * from './decorators/index';
|
|
12
13
|
export * from './auth/index';
|
|
14
|
+
export * from './sentry/index';
|
|
13
15
|
export * from './shared.module';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./database"), exports);
|
|
18
18
|
__exportStar(require("./exception/exception.filter"), exports);
|
|
19
|
+
__exportStar(require("./exception/unified-exception.filter"), exports);
|
|
19
20
|
__exportStar(require("./generic-repository"), exports);
|
|
20
21
|
__exportStar(require("./logger"), exports);
|
|
21
22
|
__exportStar(require("./pipes/custom-validation.pipe"), exports);
|
|
@@ -26,5 +27,6 @@ __exportStar(require("./schemas/schema.module"), exports);
|
|
|
26
27
|
__exportStar(require("./cluster/index"), exports);
|
|
27
28
|
__exportStar(require("./decorators/index"), exports);
|
|
28
29
|
__exportStar(require("./auth/index"), exports);
|
|
30
|
+
__exportStar(require("./sentry/index"), exports);
|
|
29
31
|
__exportStar(require("./shared.module"), exports);
|
|
30
32
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,6CAA2B;AAC3B,+DAA6C;AAC7C,uDAAqC;AAErC,2CAAyB;AAEzB,iEAA+C;AAC/C,kEAA+C;AAC/C,uEAAqD;AAErD,4CAA0B;AAC1B,0DAAwC;AAExC,kDAAgC;AAEhC,qDAAmC;AAEnC,+CAA6B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,6CAA2B;AAC3B,+DAA6C;AAC7C,uEAAqD;AACrD,uDAAqC;AAErC,2CAAyB;AAEzB,iEAA+C;AAC/C,kEAA+C;AAC/C,uEAAqD;AAErD,4CAA0B;AAC1B,0DAAwC;AAExC,kDAAgC;AAEhC,qDAAmC;AAEnC,+CAA6B;AAE7B,iDAA+B;AAG/B,kDAAgC"}
|
|
@@ -2,13 +2,17 @@ import { LoggerService } from '@nestjs/common';
|
|
|
2
2
|
export declare class CustomLogger implements LoggerService {
|
|
3
3
|
private readonly context?;
|
|
4
4
|
private readonly isProduction;
|
|
5
|
+
private readonly sentryOptions;
|
|
5
6
|
constructor(context?: string);
|
|
7
|
+
private buildExcludePatterns;
|
|
6
8
|
private getTimestamp;
|
|
7
9
|
private formatMessage;
|
|
8
10
|
private colorize;
|
|
11
|
+
private captureToSentry;
|
|
9
12
|
log(message: string, context?: string): void;
|
|
10
13
|
error(message: string, metadata?: any): void;
|
|
11
|
-
warn(message: string, context?:
|
|
14
|
+
warn(message: string, context?: any): void;
|
|
12
15
|
debug(message: string, context?: string): void;
|
|
13
16
|
verbose(message: string, context?: string): void;
|
|
17
|
+
errorWithException(message: string, exception: Error, context?: string): void;
|
|
14
18
|
}
|
|
@@ -2,10 +2,25 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CustomLogger = void 0;
|
|
4
4
|
const colorette_1 = require("colorette");
|
|
5
|
+
const sentry_logger_helper_1 = require("../sentry/sentry-logger.helper");
|
|
5
6
|
class CustomLogger {
|
|
6
7
|
constructor(context) {
|
|
7
8
|
this.context = context;
|
|
8
9
|
this.isProduction = process.env.NODE_ENV === 'production';
|
|
10
|
+
this.sentryOptions = {
|
|
11
|
+
enabled: process.env.SENTRY_ENABLED?.toLowerCase() !== 'false' && !!process.env.SENTRY_DSN,
|
|
12
|
+
rateLimitPerMinute: parseInt(process.env.SENTRY_LOGGER_RATE_LIMIT || '30', 10),
|
|
13
|
+
excludePatterns: this.buildExcludePatterns(),
|
|
14
|
+
sensitiveFields: ['password', 'token', 'secret', 'key', 'credential'],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
buildExcludePatterns() {
|
|
18
|
+
const patterns = [];
|
|
19
|
+
patterns.push(/health\s*check/i);
|
|
20
|
+
patterns.push(/ping/i);
|
|
21
|
+
patterns.push(/connection\s*established/i);
|
|
22
|
+
patterns.push(/server\s*started/i);
|
|
23
|
+
return patterns;
|
|
9
24
|
}
|
|
10
25
|
getTimestamp() {
|
|
11
26
|
const localeStringOptions = {
|
|
@@ -49,6 +64,9 @@ class CustomLogger {
|
|
|
49
64
|
return level;
|
|
50
65
|
}
|
|
51
66
|
}
|
|
67
|
+
captureToSentry(message, level, context, metadata) {
|
|
68
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureMessage(message, level, context || this.context, metadata, this.sentryOptions);
|
|
69
|
+
}
|
|
52
70
|
log(message, context) {
|
|
53
71
|
console.log(this.formatMessage('LOG', message, context));
|
|
54
72
|
}
|
|
@@ -61,9 +79,11 @@ class CustomLogger {
|
|
|
61
79
|
else {
|
|
62
80
|
console.error(baseLog);
|
|
63
81
|
}
|
|
82
|
+
this.captureToSentry(message, 'error', this.context, metadata);
|
|
64
83
|
}
|
|
65
84
|
warn(message, context) {
|
|
66
85
|
console.warn(this.formatMessage('WARN', message, context));
|
|
86
|
+
this.captureToSentry(message, 'warning', context);
|
|
67
87
|
}
|
|
68
88
|
debug(message, context) {
|
|
69
89
|
console.debug(this.formatMessage('DEBUG', message, context));
|
|
@@ -71,6 +91,13 @@ class CustomLogger {
|
|
|
71
91
|
verbose(message, context) {
|
|
72
92
|
console.log(this.formatMessage('VERBOSE', message, context));
|
|
73
93
|
}
|
|
94
|
+
errorWithException(message, exception, context) {
|
|
95
|
+
const baseLog = this.formatMessage('ERROR', message, context);
|
|
96
|
+
console.error(baseLog);
|
|
97
|
+
console.error((0, colorette_1.red)('Exception:'), exception.message);
|
|
98
|
+
console.error((0, colorette_1.red)('Stack:'), exception.stack);
|
|
99
|
+
sentry_logger_helper_1.SentryLoggerHelper.captureException(exception, message, context || this.context, this.sentryOptions);
|
|
100
|
+
}
|
|
74
101
|
}
|
|
75
102
|
exports.CustomLogger = CustomLogger;
|
|
76
103
|
//# sourceMappingURL=custom.logger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.logger.js","sourceRoot":"","sources":["../../src/logger/custom.logger.ts"],"names":[],"mappings":";;;AACA,yCAAiE;
|
|
1
|
+
{"version":3,"file":"custom.logger.js","sourceRoot":"","sources":["../../src/logger/custom.logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare class ExampleServiceWithLogger {
|
|
2
|
+
private readonly logger;
|
|
3
|
+
processUserData(userData: any): Promise<any>;
|
|
4
|
+
handleDatabaseOperation(): Promise<void>;
|
|
5
|
+
handleExternalApiCall(): Promise<{
|
|
6
|
+
data: string;
|
|
7
|
+
}>;
|
|
8
|
+
demonstrateLogLevels(): void;
|
|
9
|
+
private simulateBusinessLogic;
|
|
10
|
+
private simulateDatabaseCall;
|
|
11
|
+
private simulateApiCall;
|
|
12
|
+
}
|
|
13
|
+
export declare class ExampleController {
|
|
14
|
+
private readonly exampleService;
|
|
15
|
+
private readonly logger;
|
|
16
|
+
constructor(exampleService: ExampleServiceWithLogger);
|
|
17
|
+
createUser(userData: any): Promise<any>;
|
|
18
|
+
healthCheck(): {
|
|
19
|
+
status: string;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
};
|
|
22
|
+
testLogs(): {
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export declare class ErrorHandlingExamples {
|
|
27
|
+
private readonly logger;
|
|
28
|
+
simpleErrorHandling(): Promise<void>;
|
|
29
|
+
errorWithMetadata(): Promise<void>;
|
|
30
|
+
exceptionObjectLogging(): Promise<void>;
|
|
31
|
+
businessWarning(): Promise<void>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var ExampleServiceWithLogger_1, ExampleController_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ErrorHandlingExamples = exports.ExampleController = exports.ExampleServiceWithLogger = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const custom_logger_1 = require("../custom.logger");
|
|
19
|
+
let ExampleServiceWithLogger = ExampleServiceWithLogger_1 = class ExampleServiceWithLogger {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.logger = new custom_logger_1.CustomLogger(ExampleServiceWithLogger_1.name);
|
|
22
|
+
}
|
|
23
|
+
async processUserData(userData) {
|
|
24
|
+
try {
|
|
25
|
+
this.logger.log('Starting user data processing');
|
|
26
|
+
if (!userData.email) {
|
|
27
|
+
this.logger.warn('User data missing email field', 'ValidationWarning');
|
|
28
|
+
throw new Error('Email is required');
|
|
29
|
+
}
|
|
30
|
+
const result = await this.simulateBusinessLogic(userData);
|
|
31
|
+
this.logger.log('User data processed successfully');
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
this.logger.error('Failed to process user data', {
|
|
36
|
+
userId: userData.id,
|
|
37
|
+
email: userData.email,
|
|
38
|
+
errorMessage: error.message,
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
});
|
|
41
|
+
this.logger.errorWithException('User data processing failed with exception', error, 'UserDataProcessing');
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async handleDatabaseOperation() {
|
|
46
|
+
try {
|
|
47
|
+
await this.simulateDatabaseCall();
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.logger.errorWithException('Database operation failed', error, 'DatabaseOperation');
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async handleExternalApiCall() {
|
|
55
|
+
try {
|
|
56
|
+
const response = await this.simulateApiCall();
|
|
57
|
+
return response;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
this.logger.error('External API call failed', {
|
|
61
|
+
apiEndpoint: 'https://api.example.com/users',
|
|
62
|
+
method: 'POST',
|
|
63
|
+
statusCode: error.status || 'unknown',
|
|
64
|
+
responseBody: error.response?.data || 'no response',
|
|
65
|
+
retryCount: 3,
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
});
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
demonstrateLogLevels() {
|
|
72
|
+
this.logger.log('This is a normal log message');
|
|
73
|
+
this.logger.debug('Debug information for development');
|
|
74
|
+
this.logger.verbose('Verbose logging information');
|
|
75
|
+
this.logger.warn('This is a warning that will be sent to Sentry');
|
|
76
|
+
this.logger.error('This is an error that will be sent to Sentry');
|
|
77
|
+
this.logger.error('Error with metadata', {
|
|
78
|
+
userId: '12345',
|
|
79
|
+
action: 'user_creation',
|
|
80
|
+
details: 'Validation failed for required fields'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async simulateBusinessLogic(userData) {
|
|
84
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
85
|
+
if (Math.random() < 0.3) {
|
|
86
|
+
throw new Error('Business logic validation failed');
|
|
87
|
+
}
|
|
88
|
+
return { id: Date.now(), ...userData, processed: true };
|
|
89
|
+
}
|
|
90
|
+
async simulateDatabaseCall() {
|
|
91
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
92
|
+
if (Math.random() < 0.2) {
|
|
93
|
+
const error = new Error('Database connection timeout');
|
|
94
|
+
error.name = 'DatabaseError';
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
return { success: true };
|
|
98
|
+
}
|
|
99
|
+
async simulateApiCall() {
|
|
100
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
101
|
+
if (Math.random() < 0.25) {
|
|
102
|
+
const error = new Error('API request failed');
|
|
103
|
+
error.name = 'ApiError';
|
|
104
|
+
error.status = 500;
|
|
105
|
+
error.response = { data: 'Internal server error' };
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
return { data: 'API response data' };
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
exports.ExampleServiceWithLogger = ExampleServiceWithLogger;
|
|
112
|
+
exports.ExampleServiceWithLogger = ExampleServiceWithLogger = ExampleServiceWithLogger_1 = __decorate([
|
|
113
|
+
(0, common_1.Injectable)()
|
|
114
|
+
], ExampleServiceWithLogger);
|
|
115
|
+
const common_2 = require("@nestjs/common");
|
|
116
|
+
let ExampleController = ExampleController_1 = class ExampleController {
|
|
117
|
+
constructor(exampleService) {
|
|
118
|
+
this.exampleService = exampleService;
|
|
119
|
+
this.logger = new custom_logger_1.CustomLogger(ExampleController_1.name);
|
|
120
|
+
}
|
|
121
|
+
async createUser(userData) {
|
|
122
|
+
this.logger.log(`Creating user with email: ${userData.email}`);
|
|
123
|
+
try {
|
|
124
|
+
const result = await this.exampleService.processUserData(userData);
|
|
125
|
+
this.logger.log('User created successfully');
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this.logger.errorWithException('User creation failed at controller level', error, 'UserController');
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
healthCheck() {
|
|
134
|
+
this.logger.log('Health check requested');
|
|
135
|
+
return { status: 'ok', timestamp: new Date().toISOString() };
|
|
136
|
+
}
|
|
137
|
+
testLogs() {
|
|
138
|
+
this.logger.log('Testing different log levels');
|
|
139
|
+
this.exampleService.demonstrateLogLevels();
|
|
140
|
+
return { message: 'Log levels tested - check console and Sentry' };
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
exports.ExampleController = ExampleController;
|
|
144
|
+
__decorate([
|
|
145
|
+
(0, common_2.Post)('users'),
|
|
146
|
+
__param(0, (0, common_2.Body)()),
|
|
147
|
+
__metadata("design:type", Function),
|
|
148
|
+
__metadata("design:paramtypes", [Object]),
|
|
149
|
+
__metadata("design:returntype", Promise)
|
|
150
|
+
], ExampleController.prototype, "createUser", null);
|
|
151
|
+
__decorate([
|
|
152
|
+
(0, common_2.Get)('health'),
|
|
153
|
+
__metadata("design:type", Function),
|
|
154
|
+
__metadata("design:paramtypes", []),
|
|
155
|
+
__metadata("design:returntype", void 0)
|
|
156
|
+
], ExampleController.prototype, "healthCheck", null);
|
|
157
|
+
__decorate([
|
|
158
|
+
(0, common_2.Get)('test-logs'),
|
|
159
|
+
__metadata("design:type", Function),
|
|
160
|
+
__metadata("design:paramtypes", []),
|
|
161
|
+
__metadata("design:returntype", void 0)
|
|
162
|
+
], ExampleController.prototype, "testLogs", null);
|
|
163
|
+
exports.ExampleController = ExampleController = ExampleController_1 = __decorate([
|
|
164
|
+
(0, common_2.Controller)('example'),
|
|
165
|
+
__metadata("design:paramtypes", [ExampleServiceWithLogger])
|
|
166
|
+
], ExampleController);
|
|
167
|
+
class ErrorHandlingExamples {
|
|
168
|
+
constructor() {
|
|
169
|
+
this.logger = new custom_logger_1.CustomLogger(ErrorHandlingExamples.name);
|
|
170
|
+
}
|
|
171
|
+
async simpleErrorHandling() {
|
|
172
|
+
try {
|
|
173
|
+
throw new Error('Something went wrong');
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
this.logger.error('Operation failed', error.message);
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async errorWithMetadata() {
|
|
181
|
+
try {
|
|
182
|
+
throw new Error('Validation failed');
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
this.logger.error('Validation error occurred', {
|
|
186
|
+
operation: 'user_validation',
|
|
187
|
+
input: 'user_data',
|
|
188
|
+
errorType: error.constructor.name,
|
|
189
|
+
timestamp: new Date().toISOString(),
|
|
190
|
+
});
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async exceptionObjectLogging() {
|
|
195
|
+
try {
|
|
196
|
+
throw new Error('Database connection failed');
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
this.logger.errorWithException('Failed to connect to database', error, 'DatabaseConnection');
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async businessWarning() {
|
|
204
|
+
const userAge = 15;
|
|
205
|
+
if (userAge < 18) {
|
|
206
|
+
this.logger.warn('User under 18 attempting to access restricted content', 'AgeRestriction');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.ErrorHandlingExamples = ErrorHandlingExamples;
|
|
211
|
+
//# sourceMappingURL=logger-sentry.example.js.map
|