@myko.pk/response 1.0.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.
@@ -0,0 +1,391 @@
1
+ 'use strict';
2
+
3
+ var common = require('@nestjs/common');
4
+ var logger = require('@myko.pk/logger');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __decorateClass = (decorators, target, key, kind) => {
10
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
11
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
+ if (decorator = decorators[i])
13
+ result = (decorator(result)) || result;
14
+ return result;
15
+ };
16
+ var ERROR_TITLES = {
17
+ 400: "Bad Request",
18
+ 401: "Unauthorized",
19
+ 403: "Forbidden",
20
+ 404: "Page Not Found",
21
+ 405: "Method Not Allowed",
22
+ 408: "Request Timeout",
23
+ 409: "Conflict",
24
+ 410: "Gone",
25
+ 422: "Unprocessable Entity",
26
+ 429: "Too Many Requests",
27
+ 500: "Internal Server Error",
28
+ 502: "Bad Gateway",
29
+ 503: "Service Unavailable",
30
+ 504: "Gateway Timeout"
31
+ };
32
+ var ERROR_DESCRIPTIONS = {
33
+ 400: "The request could not be processed due to invalid data. Please check your input and try again.",
34
+ 401: "You need to be signed in to access this page. Please sign in and try again.",
35
+ 403: "You don't have permission to access this page. If you believe this is a mistake, contact support.",
36
+ 404: "The page you're looking for doesn't exist or has been moved. Check the URL and try again.",
37
+ 405: "This page does not support the request method used.",
38
+ 408: "The server timed out waiting for your request. Please try again.",
39
+ 409: "The request could not be completed due to a conflict with the current state of the resource.",
40
+ 422: "The submitted data could not be processed. Please review your input and try again.",
41
+ 429: "Too many requests. Please wait a moment before trying again.",
42
+ 500: "Something went wrong on our end. Please try again later.",
43
+ 502: "The server received an invalid response from an upstream server. Please try again later.",
44
+ 503: "The server is temporarily unavailable. Please try again later.",
45
+ 504: "The server timed out waiting for an upstream server. Please try again later."
46
+ };
47
+ function getErrorTitle(statusCode) {
48
+ return ERROR_TITLES[statusCode] || "Something Went Wrong";
49
+ }
50
+ __name(getErrorTitle, "getErrorTitle");
51
+ function getErrorDescription(statusCode) {
52
+ return ERROR_DESCRIPTIONS[statusCode] || "An unexpected error occurred. Please try again later.";
53
+ }
54
+ __name(getErrorDescription, "getErrorDescription");
55
+ function isBrowserRequest(request) {
56
+ const accept = request.headers?.accept;
57
+ return typeof accept === "string" && accept.includes("text/html");
58
+ }
59
+ __name(isBrowserRequest, "isBrowserRequest");
60
+ exports.GlobalExceptionFilter = class GlobalExceptionFilter {
61
+ logger = new logger.Logger(exports.GlobalExceptionFilter.name);
62
+ catch(exception, host) {
63
+ const ctx = host.switchToHttp();
64
+ const response = ctx.getResponse();
65
+ const request = ctx.getRequest();
66
+ const requestId = request.headers["x-request-id"];
67
+ let statusCode = common.HttpStatus.INTERNAL_SERVER_ERROR;
68
+ let message = "Internal server error";
69
+ let errorCode = "INTERNAL_ERROR";
70
+ let details = void 0;
71
+ if (exception instanceof common.HttpException) {
72
+ statusCode = exception.getStatus();
73
+ const exceptionResponse = exception.getResponse();
74
+ if (typeof exceptionResponse === "object") {
75
+ const responseObj = exceptionResponse;
76
+ message = responseObj.message || exception.message;
77
+ details = responseObj.error || responseObj.errors;
78
+ errorCode = responseObj.code || exception.constructor.name.replace("Exception", "").toUpperCase();
79
+ if (exception instanceof common.BadRequestException && !responseObj.code) {
80
+ errorCode = "VALIDATION_ERROR";
81
+ message = "Validation failed";
82
+ }
83
+ } else {
84
+ message = exceptionResponse;
85
+ errorCode = exception.constructor.name.replace("Exception", "").toUpperCase();
86
+ }
87
+ } else if (exception instanceof Error) {
88
+ message = exception.message;
89
+ errorCode = exception.name || "ERROR";
90
+ }
91
+ const errorResponse = {
92
+ success: false,
93
+ statusCode,
94
+ message,
95
+ error: {
96
+ code: errorCode,
97
+ details
98
+ },
99
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
100
+ requestId
101
+ };
102
+ const logContext = {
103
+ statusCode,
104
+ message,
105
+ method: request.method,
106
+ url: request.url,
107
+ ip: request.ip,
108
+ userAgent: request.headers["user-agent"],
109
+ errorCode
110
+ };
111
+ if (statusCode >= 500) {
112
+ this.logger.error(`[${requestId}] ${errorCode}:`, logContext);
113
+ } else if (statusCode >= 400) {
114
+ this.logger.warn(`[${requestId}] ${errorCode}:`, logContext);
115
+ } else {
116
+ this.logger.debug(`[${requestId}] ${errorCode}:`, logContext);
117
+ }
118
+ if (response.headersSent) return;
119
+ if (isBrowserRequest(request)) {
120
+ const showMessage = statusCode < 500 || process.env.NODE_ENV !== "production";
121
+ const renderOptions = {
122
+ statusCode,
123
+ title: getErrorTitle(statusCode),
124
+ description: getErrorDescription(statusCode),
125
+ message: showMessage ? message : "Something went wrong. Please try again later.",
126
+ errorCode,
127
+ showMessage
128
+ };
129
+ response.setHeader(
130
+ "Content-Security-Policy",
131
+ "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'"
132
+ );
133
+ response.status(statusCode);
134
+ response.render("error", renderOptions, (renderErr, html) => {
135
+ if (renderErr) {
136
+ this.logger.error(`[${requestId}] Failed to render error page:`, renderErr);
137
+ return response.json(errorResponse);
138
+ }
139
+ response.send(html);
140
+ });
141
+ } else {
142
+ response.status(statusCode).json(errorResponse);
143
+ }
144
+ }
145
+ };
146
+ __name(exports.GlobalExceptionFilter, "GlobalExceptionFilter");
147
+ exports.GlobalExceptionFilter = __decorateClass([
148
+ common.Catch()
149
+ ], exports.GlobalExceptionFilter);
150
+ exports.ValidationExceptionFilter = class ValidationExceptionFilter {
151
+ logger = new logger.Logger(exports.ValidationExceptionFilter.name);
152
+ catch(exception, host) {
153
+ const ctx = host.switchToHttp();
154
+ const response = ctx.getResponse();
155
+ const request = ctx.getRequest();
156
+ const requestId = request.headers["x-request-id"];
157
+ const exceptionResponse = exception.getResponse();
158
+ const rawErrors = exceptionResponse.message;
159
+ const errors = Array.isArray(rawErrors) ? rawErrors : typeof rawErrors === "string" ? [rawErrors] : [];
160
+ const formattedErrors = this.formatValidationErrors(errors);
161
+ const errorResponse = {
162
+ success: false,
163
+ statusCode: 400,
164
+ message: "Validation failed",
165
+ error: {
166
+ code: "VALIDATION_ERROR",
167
+ details: formattedErrors
168
+ },
169
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
170
+ requestId
171
+ };
172
+ this.logger.warn(`[${requestId}] Validation error:`, {
173
+ method: request.method,
174
+ url: request.url,
175
+ errors: formattedErrors
176
+ });
177
+ response.status(400).json(errorResponse);
178
+ }
179
+ /**
180
+ * Format validation errors from class-validator
181
+ */
182
+ formatValidationErrors(errors) {
183
+ const messages = [];
184
+ if (Array.isArray(errors)) {
185
+ errors.forEach((error) => {
186
+ if (typeof error === "string") {
187
+ messages.push(error);
188
+ } else if (error?.constraints) {
189
+ messages.push(...Object.values(error.constraints));
190
+ }
191
+ });
192
+ }
193
+ return messages;
194
+ }
195
+ };
196
+ __name(exports.ValidationExceptionFilter, "ValidationExceptionFilter");
197
+ exports.ValidationExceptionFilter = __decorateClass([
198
+ common.Catch(common.BadRequestException)
199
+ ], exports.ValidationExceptionFilter);
200
+ exports.HttpExceptionFilter = class HttpExceptionFilter {
201
+ logger = new logger.Logger(exports.HttpExceptionFilter.name);
202
+ catch(exception, host) {
203
+ const ctx = host.switchToHttp();
204
+ const response = ctx.getResponse();
205
+ const request = ctx.getRequest();
206
+ const requestId = request.headers["x-request-id"];
207
+ const statusCode = exception.getStatus();
208
+ const exceptionResponse = exception.getResponse();
209
+ const message = typeof exceptionResponse === "string" ? exceptionResponse : exceptionResponse.message || exception.message;
210
+ const errorCode = this.getErrorCode(exception, statusCode);
211
+ const errorResponse = {
212
+ success: false,
213
+ statusCode,
214
+ message,
215
+ error: {
216
+ code: errorCode,
217
+ details: exceptionResponse.error || exceptionResponse.errors
218
+ },
219
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
220
+ requestId
221
+ };
222
+ const logContext = {
223
+ statusCode,
224
+ message,
225
+ method: request.method,
226
+ url: request.url,
227
+ ip: request.ip
228
+ };
229
+ if (statusCode >= 500) {
230
+ this.logger.error(`[${requestId}] ${errorCode}:`, logContext);
231
+ } else if (statusCode >= 400) {
232
+ this.logger.warn(`[${requestId}] ${errorCode}:`, logContext);
233
+ }
234
+ response.status(statusCode).json(errorResponse);
235
+ }
236
+ /**
237
+ * Get error code from exception type
238
+ */
239
+ getErrorCode(exception, statusCode) {
240
+ const exceptionName = exception.constructor.name;
241
+ const errorCodeMap = {
242
+ 400: "BAD_REQUEST",
243
+ 401: "UNAUTHORIZED",
244
+ 403: "FORBIDDEN",
245
+ 404: "NOT_FOUND",
246
+ 409: "CONFLICT",
247
+ 422: "UNPROCESSABLE_ENTITY",
248
+ 429: "TOO_MANY_REQUESTS",
249
+ 500: "INTERNAL_SERVER_ERROR",
250
+ 502: "BAD_GATEWAY",
251
+ 503: "SERVICE_UNAVAILABLE"
252
+ };
253
+ return errorCodeMap[statusCode] || exceptionName.replace("Exception", "").toUpperCase();
254
+ }
255
+ };
256
+ __name(exports.HttpExceptionFilter, "HttpExceptionFilter");
257
+ exports.HttpExceptionFilter = __decorateClass([
258
+ common.Catch(common.HttpException)
259
+ ], exports.HttpExceptionFilter);
260
+ exports.DatabaseExceptionFilter = class DatabaseExceptionFilter {
261
+ logger = new logger.Logger(exports.DatabaseExceptionFilter.name);
262
+ catch(exception, host) {
263
+ const ctx = host.switchToHttp();
264
+ const response = ctx.getResponse();
265
+ const request = ctx.getRequest();
266
+ const requestId = request.headers["x-request-id"];
267
+ if (!this.isDatabaseError(exception)) {
268
+ throw exception;
269
+ }
270
+ const { statusCode, message, errorCode } = this.parseError(exception);
271
+ const errorResponse = {
272
+ success: false,
273
+ statusCode,
274
+ message,
275
+ error: {
276
+ code: errorCode
277
+ },
278
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
279
+ requestId
280
+ };
281
+ this.logger.error(`[${requestId}] Database error:`, {
282
+ statusCode,
283
+ message,
284
+ errorCode,
285
+ method: request.method,
286
+ url: request.url,
287
+ // Log full error details in development only
288
+ ...process.env.NODE_ENV !== "production" && { details: exception.message }
289
+ });
290
+ response.status(statusCode).json(errorResponse);
291
+ }
292
+ /**
293
+ * Check if exception is a database error
294
+ */
295
+ isDatabaseError(exception) {
296
+ const errorName = exception.constructor.name;
297
+ const errorMessage = exception.message || "";
298
+ if (errorName.includes("QueryFailedError") || errorName.includes("EntityNotFound")) {
299
+ return true;
300
+ }
301
+ if (errorName.includes("PrismaClientKnownRequestError") || errorName.includes("PrismaClientValidationError")) {
302
+ return true;
303
+ }
304
+ if (errorMessage.includes("UNIQUE constraint failed") || errorMessage.includes("Foreign key constraint") || errorMessage.includes("Duplicate entry") || errorMessage.includes("violates unique constraint")) {
305
+ return true;
306
+ }
307
+ return false;
308
+ }
309
+ /**
310
+ * Parse database error and return user-friendly message
311
+ */
312
+ parseError(exception) {
313
+ const errorMessage = exception.message || "";
314
+ const errorCode = exception.code || "DATABASE_ERROR";
315
+ if (errorMessage.includes("UNIQUE constraint failed") || errorMessage.includes("Duplicate entry") || errorMessage.includes("violates unique constraint") || errorCode === "P2002") {
316
+ return {
317
+ statusCode: 409,
318
+ message: "This record already exists",
319
+ errorCode: "DUPLICATE_ENTRY"
320
+ };
321
+ }
322
+ if (errorMessage.includes("Foreign key constraint") || errorMessage.includes("FOREIGN KEY constraint failed") || errorCode === "P2003") {
323
+ return {
324
+ statusCode: 400,
325
+ message: "Invalid reference to related record",
326
+ errorCode: "INVALID_REFERENCE"
327
+ };
328
+ }
329
+ if (errorMessage.includes("No entity found") || errorCode === "P2025") {
330
+ return {
331
+ statusCode: 404,
332
+ message: "Record not found",
333
+ errorCode: "NOT_FOUND"
334
+ };
335
+ }
336
+ if (errorMessage.includes("Validation failed") || errorCode === "P2007") {
337
+ return {
338
+ statusCode: 400,
339
+ message: "Invalid data provided",
340
+ errorCode: "VALIDATION_ERROR"
341
+ };
342
+ }
343
+ return {
344
+ statusCode: 500,
345
+ message: "Database operation failed",
346
+ errorCode: "DATABASE_ERROR"
347
+ };
348
+ }
349
+ };
350
+ __name(exports.DatabaseExceptionFilter, "DatabaseExceptionFilter");
351
+ exports.DatabaseExceptionFilter = __decorateClass([
352
+ common.Catch()
353
+ ], exports.DatabaseExceptionFilter);
354
+ exports.AuthExceptionFilter = class AuthExceptionFilter {
355
+ logger = new logger.Logger(exports.AuthExceptionFilter.name);
356
+ catch(exception, host) {
357
+ const ctx = host.switchToHttp();
358
+ const response = ctx.getResponse();
359
+ const request = ctx.getRequest();
360
+ const requestId = request.headers["x-request-id"];
361
+ const statusCode = exception.getStatus();
362
+ const exceptionResponse = exception.getResponse();
363
+ const message = typeof exceptionResponse === "string" ? exceptionResponse : exceptionResponse.message || exception.message;
364
+ const errorCode = statusCode === 401 ? "UNAUTHORIZED" : "FORBIDDEN";
365
+ const errorResponse = {
366
+ success: false,
367
+ statusCode,
368
+ message,
369
+ error: {
370
+ code: errorCode
371
+ },
372
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
373
+ requestId
374
+ };
375
+ this.logger.warn(`[${requestId}] Auth error:`, {
376
+ statusCode,
377
+ message,
378
+ errorCode,
379
+ method: request.method,
380
+ url: request.url,
381
+ ip: request.ip
382
+ });
383
+ response.status(statusCode).json(errorResponse);
384
+ }
385
+ };
386
+ __name(exports.AuthExceptionFilter, "AuthExceptionFilter");
387
+ exports.AuthExceptionFilter = __decorateClass([
388
+ common.Catch(common.UnauthorizedException, common.ForbiddenException)
389
+ ], exports.AuthExceptionFilter);
390
+ //# sourceMappingURL=index.cjs.map
391
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/filters/global-exception.filter.ts","../../src/filters/validation.filter.ts","../../src/filters/http-exception.filter.ts","../../src/filters/database.filter.ts","../../src/filters/auth.filter.ts"],"names":["GlobalExceptionFilter","Logger","HttpStatus","HttpException","BadRequestException","Catch","ValidationExceptionFilter","HttpExceptionFilter","DatabaseExceptionFilter","AuthExceptionFilter","UnauthorizedException","ForbiddenException"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus, BadRequestException } from '@nestjs/common';\nimport { Logger } from '@myko.pk/logger';\nimport { Request, Response } from 'express';\n\nconst ERROR_TITLES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Page Not Found',\n 405: 'Method Not Allowed',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n};\n\nconst ERROR_DESCRIPTIONS: Record<number, string> = {\n 400: 'The request could not be processed due to invalid data. Please check your input and try again.',\n 401: 'You need to be signed in to access this page. Please sign in and try again.',\n 403: \"You don't have permission to access this page. If you believe this is a mistake, contact support.\",\n 404: \"The page you're looking for doesn't exist or has been moved. Check the URL and try again.\",\n 405: 'This page does not support the request method used.',\n 408: 'The server timed out waiting for your request. Please try again.',\n 409: 'The request could not be completed due to a conflict with the current state of the resource.',\n 422: 'The submitted data could not be processed. Please review your input and try again.',\n 429: 'Too many requests. Please wait a moment before trying again.',\n 500: 'Something went wrong on our end. Please try again later.',\n 502: 'The server received an invalid response from an upstream server. Please try again later.',\n 503: 'The server is temporarily unavailable. Please try again later.',\n 504: 'The server timed out waiting for an upstream server. Please try again later.',\n};\n\nfunction getErrorTitle(statusCode: number): string {\n return ERROR_TITLES[statusCode] || 'Something Went Wrong';\n}\n\nfunction getErrorDescription(statusCode: number): string {\n return ERROR_DESCRIPTIONS[statusCode] || 'An unexpected error occurred. Please try again later.';\n}\n\nfunction isBrowserRequest(request: Request): boolean {\n const accept = request.headers?.accept;\n return typeof accept === 'string' && accept.includes('text/html');\n}\n\n@Catch()\nexport class GlobalExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(GlobalExceptionFilter.name);\n\n catch(exception: any, host: ArgumentsHost) {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n const requestId = request.headers['x-request-id'] as string | undefined;\n\n let statusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n let message = 'Internal server error';\n let errorCode = 'INTERNAL_ERROR';\n let details: any = undefined;\n\n if (exception instanceof HttpException) {\n statusCode = exception.getStatus();\n const exceptionResponse = exception.getResponse();\n\n if (typeof exceptionResponse === 'object') {\n const responseObj = exceptionResponse as any;\n message = responseObj.message || exception.message;\n details = responseObj.error || responseObj.errors;\n errorCode = responseObj.code || exception.constructor.name.replace('Exception', '').toUpperCase();\n\n if (exception instanceof BadRequestException && !responseObj.code) {\n errorCode = 'VALIDATION_ERROR';\n message = 'Validation failed';\n }\n } else {\n message = exceptionResponse as string;\n errorCode = exception.constructor.name.replace('Exception', '').toUpperCase();\n }\n } else if (exception instanceof Error) {\n message = exception.message;\n errorCode = exception.name || 'ERROR';\n }\n\n const errorResponse = {\n success: false,\n statusCode,\n message,\n error: {\n code: errorCode,\n details: details,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n\n // Log error with appropriate level\n const logContext = {\n statusCode,\n message,\n method: request.method,\n url: request.url,\n ip: request.ip,\n userAgent: request.headers['user-agent'],\n errorCode,\n };\n\n if (statusCode >= 500) {\n this.logger.error(`[${requestId}] ${errorCode}:`, logContext);\n } else if (statusCode >= 400) {\n this.logger.warn(`[${requestId}] ${errorCode}:`, logContext);\n } else {\n this.logger.debug(`[${requestId}] ${errorCode}:`, logContext);\n }\n\n if (response.headersSent) return;\n\n // Render error page for browser requests, JSON for API requests\n if (isBrowserRequest(request)) {\n const showMessage = statusCode < 500 || process.env.NODE_ENV !== 'production';\n const renderOptions = {\n statusCode,\n title: getErrorTitle(statusCode),\n description: getErrorDescription(statusCode),\n message: showMessage ? message : 'Something went wrong. Please try again later.',\n errorCode,\n showMessage,\n };\n\n response.setHeader('Content-Security-Policy',\n \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'\",\n );\n\n response.status(statusCode);\n response.render('error', renderOptions, (renderErr: any, html: string) => {\n if (renderErr) {\n this.logger.error(`[${requestId}] Failed to render error page:`, renderErr);\n return response.json(errorResponse);\n }\n response.send(html);\n });\n } else {\n response.status(statusCode).json(errorResponse);\n }\n }\n}\n","import { ExceptionFilter, Catch, ArgumentsHost, BadRequestException } from '@nestjs/common';\nimport { Logger } from '@myko.pk/logger';\nimport { Response } from 'express';\n\n/**\n * Validation Exception Filter\n * Handles validation errors from class-validator and pipes\n * Formats validation errors in a user-friendly way\n */\n@Catch(BadRequestException)\nexport class ValidationExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(ValidationExceptionFilter.name);\n\n catch(exception: BadRequestException, host: ArgumentsHost) {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest();\n const requestId = request.headers['x-request-id'];\n\n const exceptionResponse = exception.getResponse() as any;\n const rawErrors = exceptionResponse.message;\n const errors = Array.isArray(rawErrors) ? rawErrors : typeof rawErrors === 'string' ? [rawErrors] : [];\n\n // Format validation errors\n const formattedErrors = this.formatValidationErrors(errors);\n\n const errorResponse = {\n success: false,\n statusCode: 400,\n message: 'Validation failed',\n error: {\n code: 'VALIDATION_ERROR',\n details: formattedErrors,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n\n this.logger.warn(`[${requestId}] Validation error:`, {\n method: request.method,\n url: request.url,\n errors: formattedErrors,\n });\n\n response.status(400).json(errorResponse);\n }\n\n /**\n * Format validation errors from class-validator\n */\n private formatValidationErrors(errors: any[]): string[] {\n const messages: string[] = [];\n\n if (Array.isArray(errors)) {\n errors.forEach((error) => {\n if (typeof error === 'string') {\n messages.push(error);\n } else if (error?.constraints) {\n messages.push(...Object.values(error.constraints) as string[]);\n }\n });\n }\n\n return messages;\n }\n}\n","import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';\nimport { Logger } from '@myko.pk/logger';\nimport { Response } from 'express';\n\n/**\n * HTTP Exception Filter\n * Handles all HTTP exceptions with consistent formatting\n */\n@Catch(HttpException)\nexport class HttpExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(HttpExceptionFilter.name);\n\n catch(exception: HttpException, host: ArgumentsHost) {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest();\n const requestId = request.headers['x-request-id'];\n\n const statusCode = exception.getStatus();\n const exceptionResponse = exception.getResponse() as any;\n\n const message = typeof exceptionResponse === 'string' \n ? exceptionResponse \n : exceptionResponse.message || exception.message;\n\n const errorCode = this.getErrorCode(exception, statusCode);\n\n const errorResponse = {\n success: false,\n statusCode,\n message,\n error: {\n code: errorCode,\n details: exceptionResponse.error || exceptionResponse.errors,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n\n // Log based on status code\n const logContext = {\n statusCode,\n message,\n method: request.method,\n url: request.url,\n ip: request.ip,\n };\n\n if (statusCode >= 500) {\n this.logger.error(`[${requestId}] ${errorCode}:`, logContext);\n } else if (statusCode >= 400) {\n this.logger.warn(`[${requestId}] ${errorCode}:`, logContext);\n }\n\n response.status(statusCode).json(errorResponse);\n }\n\n /**\n * Get error code from exception type\n */\n private getErrorCode(exception: HttpException, statusCode: number): string {\n const exceptionName = exception.constructor.name;\n \n // Map common exceptions to error codes\n const errorCodeMap: Record<number, string> = {\n 400: 'BAD_REQUEST',\n 401: 'UNAUTHORIZED',\n 403: 'FORBIDDEN',\n 404: 'NOT_FOUND',\n 409: 'CONFLICT',\n 422: 'UNPROCESSABLE_ENTITY',\n 429: 'TOO_MANY_REQUESTS',\n 500: 'INTERNAL_SERVER_ERROR',\n 502: 'BAD_GATEWAY',\n 503: 'SERVICE_UNAVAILABLE',\n };\n\n return errorCodeMap[statusCode] || exceptionName.replace('Exception', '').toUpperCase();\n }\n}\n","import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';\nimport { Logger } from '@myko.pk/logger';\nimport { Response } from 'express';\n\n/**\n * Database Exception Filter\n * Handles database errors (TypeORM, Prisma, etc.)\n * Prevents sensitive database information from leaking\n */\n@Catch()\nexport class DatabaseExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(DatabaseExceptionFilter.name);\n\n catch(exception: any, host: ArgumentsHost) {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest();\n const requestId = request.headers['x-request-id'];\n\n // Check if it's a database error\n if (!this.isDatabaseError(exception)) {\n throw exception; // Let other filters handle it\n }\n\n const { statusCode, message, errorCode } = this.parseError(exception);\n\n const errorResponse = {\n success: false,\n statusCode,\n message,\n error: {\n code: errorCode,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n\n this.logger.error(`[${requestId}] Database error:`, {\n statusCode,\n message,\n errorCode,\n method: request.method,\n url: request.url,\n // Log full error details in development only\n ...(process.env.NODE_ENV !== 'production' && { details: exception.message }),\n });\n\n response.status(statusCode).json(errorResponse);\n }\n\n /**\n * Check if exception is a database error\n */\n private isDatabaseError(exception: any): boolean {\n const errorName = exception.constructor.name;\n const errorMessage = exception.message || '';\n\n // TypeORM errors\n if (errorName.includes('QueryFailedError') || errorName.includes('EntityNotFound')) {\n return true;\n }\n\n // Prisma errors\n if (errorName.includes('PrismaClientKnownRequestError') || errorName.includes('PrismaClientValidationError')) {\n return true;\n }\n\n // Generic database error indicators\n if (\n errorMessage.includes('UNIQUE constraint failed') ||\n errorMessage.includes('Foreign key constraint') ||\n errorMessage.includes('Duplicate entry') ||\n errorMessage.includes('violates unique constraint')\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Parse database error and return user-friendly message\n */\n private parseError(exception: any): { statusCode: number; message: string; errorCode: string } {\n const errorMessage = exception.message || '';\n const errorCode = exception.code || 'DATABASE_ERROR';\n\n // Unique constraint violation\n if (\n errorMessage.includes('UNIQUE constraint failed') ||\n errorMessage.includes('Duplicate entry') ||\n errorMessage.includes('violates unique constraint') ||\n errorCode === 'P2002'\n ) {\n return {\n statusCode: 409,\n message: 'This record already exists',\n errorCode: 'DUPLICATE_ENTRY',\n };\n }\n\n // Foreign key constraint\n if (\n errorMessage.includes('Foreign key constraint') ||\n errorMessage.includes('FOREIGN KEY constraint failed') ||\n errorCode === 'P2003'\n ) {\n return {\n statusCode: 400,\n message: 'Invalid reference to related record',\n errorCode: 'INVALID_REFERENCE',\n };\n }\n\n // Record not found\n if (errorMessage.includes('No entity found') || errorCode === 'P2025') {\n return {\n statusCode: 404,\n message: 'Record not found',\n errorCode: 'NOT_FOUND',\n };\n }\n\n // Validation error\n if (errorMessage.includes('Validation failed') || errorCode === 'P2007') {\n return {\n statusCode: 400,\n message: 'Invalid data provided',\n errorCode: 'VALIDATION_ERROR',\n };\n }\n\n // Generic database error\n return {\n statusCode: 500,\n message: 'Database operation failed',\n errorCode: 'DATABASE_ERROR',\n };\n }\n}\n","import { ExceptionFilter, Catch, ArgumentsHost, UnauthorizedException, ForbiddenException } from '@nestjs/common';\nimport { Logger } from '@myko.pk/logger';\nimport { Response } from 'express';\n\n/**\n * Authentication & Authorization Exception Filter\n * Handles auth-related errors with appropriate responses\n */\n@Catch(UnauthorizedException, ForbiddenException)\nexport class AuthExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(AuthExceptionFilter.name);\n\n catch(exception: UnauthorizedException | ForbiddenException, host: ArgumentsHost) {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest();\n const requestId = request.headers['x-request-id'];\n\n const statusCode = exception.getStatus();\n const exceptionResponse = exception.getResponse() as any;\n const message = typeof exceptionResponse === 'string' \n ? exceptionResponse \n : exceptionResponse.message || exception.message;\n\n const errorCode = statusCode === 401 ? 'UNAUTHORIZED' : 'FORBIDDEN';\n\n const errorResponse = {\n success: false,\n statusCode,\n message,\n error: {\n code: errorCode,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n\n this.logger.warn(`[${requestId}] Auth error:`, {\n statusCode,\n message,\n errorCode,\n method: request.method,\n url: request.url,\n ip: request.ip,\n });\n\n response.status(statusCode).json(errorResponse);\n }\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { ExceptionFilter, ArgumentsHost, BadRequestException, HttpException, UnauthorizedException, ForbiddenException } from '@nestjs/common';
2
+
3
+ declare class GlobalExceptionFilter implements ExceptionFilter {
4
+ private readonly logger;
5
+ catch(exception: any, host: ArgumentsHost): void;
6
+ }
7
+
8
+ /**
9
+ * Validation Exception Filter
10
+ * Handles validation errors from class-validator and pipes
11
+ * Formats validation errors in a user-friendly way
12
+ */
13
+ declare class ValidationExceptionFilter implements ExceptionFilter {
14
+ private readonly logger;
15
+ catch(exception: BadRequestException, host: ArgumentsHost): void;
16
+ /**
17
+ * Format validation errors from class-validator
18
+ */
19
+ private formatValidationErrors;
20
+ }
21
+
22
+ /**
23
+ * HTTP Exception Filter
24
+ * Handles all HTTP exceptions with consistent formatting
25
+ */
26
+ declare class HttpExceptionFilter implements ExceptionFilter {
27
+ private readonly logger;
28
+ catch(exception: HttpException, host: ArgumentsHost): void;
29
+ /**
30
+ * Get error code from exception type
31
+ */
32
+ private getErrorCode;
33
+ }
34
+
35
+ /**
36
+ * Database Exception Filter
37
+ * Handles database errors (TypeORM, Prisma, etc.)
38
+ * Prevents sensitive database information from leaking
39
+ */
40
+ declare class DatabaseExceptionFilter implements ExceptionFilter {
41
+ private readonly logger;
42
+ catch(exception: any, host: ArgumentsHost): void;
43
+ /**
44
+ * Check if exception is a database error
45
+ */
46
+ private isDatabaseError;
47
+ /**
48
+ * Parse database error and return user-friendly message
49
+ */
50
+ private parseError;
51
+ }
52
+
53
+ /**
54
+ * Authentication & Authorization Exception Filter
55
+ * Handles auth-related errors with appropriate responses
56
+ */
57
+ declare class AuthExceptionFilter implements ExceptionFilter {
58
+ private readonly logger;
59
+ catch(exception: UnauthorizedException | ForbiddenException, host: ArgumentsHost): void;
60
+ }
61
+
62
+ export { AuthExceptionFilter, DatabaseExceptionFilter, GlobalExceptionFilter, HttpExceptionFilter, ValidationExceptionFilter };
@@ -0,0 +1,62 @@
1
+ import { ExceptionFilter, ArgumentsHost, BadRequestException, HttpException, UnauthorizedException, ForbiddenException } from '@nestjs/common';
2
+
3
+ declare class GlobalExceptionFilter implements ExceptionFilter {
4
+ private readonly logger;
5
+ catch(exception: any, host: ArgumentsHost): void;
6
+ }
7
+
8
+ /**
9
+ * Validation Exception Filter
10
+ * Handles validation errors from class-validator and pipes
11
+ * Formats validation errors in a user-friendly way
12
+ */
13
+ declare class ValidationExceptionFilter implements ExceptionFilter {
14
+ private readonly logger;
15
+ catch(exception: BadRequestException, host: ArgumentsHost): void;
16
+ /**
17
+ * Format validation errors from class-validator
18
+ */
19
+ private formatValidationErrors;
20
+ }
21
+
22
+ /**
23
+ * HTTP Exception Filter
24
+ * Handles all HTTP exceptions with consistent formatting
25
+ */
26
+ declare class HttpExceptionFilter implements ExceptionFilter {
27
+ private readonly logger;
28
+ catch(exception: HttpException, host: ArgumentsHost): void;
29
+ /**
30
+ * Get error code from exception type
31
+ */
32
+ private getErrorCode;
33
+ }
34
+
35
+ /**
36
+ * Database Exception Filter
37
+ * Handles database errors (TypeORM, Prisma, etc.)
38
+ * Prevents sensitive database information from leaking
39
+ */
40
+ declare class DatabaseExceptionFilter implements ExceptionFilter {
41
+ private readonly logger;
42
+ catch(exception: any, host: ArgumentsHost): void;
43
+ /**
44
+ * Check if exception is a database error
45
+ */
46
+ private isDatabaseError;
47
+ /**
48
+ * Parse database error and return user-friendly message
49
+ */
50
+ private parseError;
51
+ }
52
+
53
+ /**
54
+ * Authentication & Authorization Exception Filter
55
+ * Handles auth-related errors with appropriate responses
56
+ */
57
+ declare class AuthExceptionFilter implements ExceptionFilter {
58
+ private readonly logger;
59
+ catch(exception: UnauthorizedException | ForbiddenException, host: ArgumentsHost): void;
60
+ }
61
+
62
+ export { AuthExceptionFilter, DatabaseExceptionFilter, GlobalExceptionFilter, HttpExceptionFilter, ValidationExceptionFilter };