Skip to content

Commit

Permalink
feat: show error stack trace in logs
Browse files Browse the repository at this point in the history
  • Loading branch information
ocamilomontealegre committed Dec 19, 2024
1 parent 2711b2a commit f466f10
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 81 deletions.
44 changes: 23 additions & 21 deletions src/common/exception-filters/http-exception.filter.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { StatusCodes } from "http-status-codes";
import { HTTPException } from "@common/exceptions/";
import { HTTPUtils } from "@common/utils";
import { HTTPResponseModel } from "@common/models";
import type { NextFunction, Request, Response } from "express";

export class HTTPExceptionFilter {
public catch(err: Error, req: Request, res: Response, _: NextFunction): void {
const statusCode =
err instanceof HTTPException ? err.statusCode : StatusCodes.INTERNAL_SERVER_ERROR;
const message = err.message ?? HTTPUtils.getHttpMessage(statusCode);

const errorResponse = new HTTPResponseModel({
status: statusCode,
success: false,
message,
});

res.status(statusCode).json(errorResponse);
}
}
import { StatusCodes } from "http-status-codes";
import { HTTPException } from "@common/exceptions/";
import { HTTPUtils } from "@common/utils";
import { HTTPResponseModel } from "@common/models";
import type { NextFunction, Request, Response } from "express";

export class HTTPExceptionFilter {
public catch(err: Error, req: Request, res: Response, _: NextFunction): void {
const statusCode =
err instanceof HTTPException ? err.statusCode : StatusCodes.INTERNAL_SERVER_ERROR;
const message = err.message ?? HTTPUtils.getHttpMessage(statusCode);

const errorResponse = new HTTPResponseModel({
status: statusCode,
success: false,
message,
});

res.locals.error = err;
res.status(statusCode).json(errorResponse);
}
}

122 changes: 62 additions & 60 deletions src/common/interceptors/http.interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,62 @@
import { StatusCodes } from "http-status-codes";
import { Logger } from "@common/logger/logger.config";
import { HTTPUtils } from "@common/utils";
import { HTTPResponseModel } from "@common/models";
import { appConfig } from "@common/env";
import type { NextFunction, Request, Response, Send } from "express";
import type { GenericObject } from "@common/types";

export class HttpInterceptor {
private readonly _logger: Logger;

public constructor() {
this._logger = new Logger(HttpInterceptor.name);
}

private _overrideResMethod(res: Response, method: Send): Send {
return (body: GenericObject): Response => {
if (res.statusCode >= StatusCodes.BAD_REQUEST) {
res.locals.httpResponse = body;
return method.call(res, body);
}

const httpResponse = new HTTPResponseModel({
message: HTTPUtils.getHttpMessage(res.statusCode),
data: body,
});
res.locals.httpResponse = httpResponse;

return method.call(res, httpResponse);
};
}

public intercept = (req: Request, res: Response, next: NextFunction): void => {
const { method, url, headers } = req;

const requestBody = req.body ? JSON.stringify(req.body) : "";

if (url.includes(`${appConfig.appDocsEndpoint}`)) {
return next();
}

const originalJson = res.json.bind(res);
res.json = this._overrideResMethod(res, originalJson);

res.on("finish", () => {
const { statusCode, locals } = res;

const logBody = `Incoming request: METHOD: ${method} | URL: ${url} | HEADERS: ${JSON.stringify(
headers,
)} | REQUEST-BODY: ${requestBody} | Outgoing response: STATUS_CODE: ${statusCode} | RESPONSE-BODY: ${JSON.stringify(
locals.httpResponse,
)}`;

if (statusCode >= StatusCodes.BAD_REQUEST) this._logger.error(logBody);
else this._logger.info(logBody);
});

next();
};
}
import { StatusCodes } from "http-status-codes";
import { Logger } from "@common/logger/logger.config";
import { HTTPUtils } from "@common/utils";
import { HTTPResponseModel } from "@common/models";
import { appConfig } from "@common/env";
import type { NextFunction, Request, Response, Send } from "express";
import type { GenericObject } from "@common/types";

export class HttpInterceptor {
private readonly logger: Logger;

public constructor() {
this.logger = new Logger(HttpInterceptor.name);
}

private overrideResMethod(res: Response, method: Send): Send {
return (body: GenericObject): Response => {
if (res.statusCode >= StatusCodes.BAD_REQUEST) {
res.locals.httpResponse = body;
return method.call(res, body);
}

const httpResponse = new HTTPResponseModel({
message: HTTPUtils.getHttpMessage(res.statusCode),
data: body,
});
res.locals.httpResponse = httpResponse;

return method.call(res, httpResponse);
};
}

public intercept = (req: Request, res: Response, next: NextFunction): void => {
const { method, url, headers } = req;

const requestBody = req.body ? JSON.stringify(req.body) : "";

if (url.includes(`${appConfig.appDocsEndpoint}`)) {
return next();
}

const originalJson = res.json.bind(res);
res.json = this.overrideResMethod(res, originalJson);

res.on("finish", () => {
const { statusCode, locals } = res;

const logBody = `Incoming request: METHOD: ${method} | URL: ${url} | HEADERS: ${JSON.stringify(
headers,
)} | REQUEST-BODY: ${requestBody} | Outgoing response: STATUS_CODE: ${statusCode} | RESPONSE-BODY: ${JSON.stringify(
locals.httpResponse,
)}`;

if (statusCode >= StatusCodes.BAD_REQUEST)
this.logger.error(`${logBody} | ERROR: ${res.locals?.error.stack}`);
else this.logger.info(logBody);
});

next();
};
}

0 comments on commit f466f10

Please sign in to comment.