improved exception filetr
This commit is contained in:
@@ -1,40 +1,71 @@
|
|||||||
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from '@nestjs/common';
|
import {
|
||||||
import { FastifyReply } from 'fastify';
|
ArgumentsHost,
|
||||||
|
Catch,
|
||||||
|
ExceptionFilter,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
Logger,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
@Catch(HttpException)
|
@Catch(HttpException)
|
||||||
export class HttpExceptionFilter implements ExceptionFilter {
|
export class HttpExceptionFilter implements ExceptionFilter {
|
||||||
|
private readonly logger = new Logger(HttpExceptionFilter.name);
|
||||||
|
|
||||||
catch(exception: HttpException, host: ArgumentsHost) {
|
catch(exception: HttpException, host: ArgumentsHost) {
|
||||||
// Handle HTTP/REST context
|
|
||||||
try {
|
try {
|
||||||
const ctx = host.switchToHttp();
|
const ctx = host.switchToHttp();
|
||||||
const reply = ctx.getResponse<FastifyReply>();
|
const reply = ctx.getResponse<FastifyReply>();
|
||||||
|
const request = ctx.getRequest<FastifyRequest>();
|
||||||
|
|
||||||
// Safety check: ensure reply has the status method
|
|
||||||
if (!reply || typeof reply.status !== 'function') {
|
if (!reply || typeof reply.status !== 'function') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const request = ctx.getRequest<FastifyRequest>();
|
|
||||||
const status = exception.getStatus() || HttpStatus.INTERNAL_SERVER_ERROR;
|
const status = exception.getStatus() || HttpStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
const exceptionResponse = exception.getResponse();
|
const exceptionResponse = exception.getResponse();
|
||||||
const message = this.extractMessage(exceptionResponse);
|
const message = this.extractMessage(exceptionResponse);
|
||||||
|
|
||||||
|
this.logError(exception, request, status, message);
|
||||||
|
|
||||||
reply.status(status).send({
|
reply.status(status).send({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
success: false,
|
success: false,
|
||||||
error: {
|
error: { message },
|
||||||
message,
|
|
||||||
// timestamp: new Date().toISOString(),
|
|
||||||
// path: request.url,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
// If we can't handle it, let it propagate
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private logError(
|
||||||
|
exception: HttpException,
|
||||||
|
request: FastifyRequest,
|
||||||
|
status: number,
|
||||||
|
message: string | string[],
|
||||||
|
) {
|
||||||
|
const logContext = {
|
||||||
|
statusCode: status,
|
||||||
|
method: request.method,
|
||||||
|
url: request.url,
|
||||||
|
ip: request.ip,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (status >= HttpStatus.INTERNAL_SERVER_ERROR) {
|
||||||
|
this.logger.error(
|
||||||
|
`[${request.method}] ${request.url} → ${status}`,
|
||||||
|
exception.stack,
|
||||||
|
JSON.stringify(logContext),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.logger.warn(
|
||||||
|
`[${request.method}] ${request.url} → ${status}`,
|
||||||
|
JSON.stringify(logContext),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private extractMessage(response: string | Record<string, any>): string | string[] {
|
private extractMessage(response: string | Record<string, any>): string | string[] {
|
||||||
if (typeof response === 'string') {
|
if (typeof response === 'string') {
|
||||||
return [response];
|
return [response];
|
||||||
|
|||||||
Reference in New Issue
Block a user