HttpExceptionFilter

34 阅读1分钟

HttpExceptionFilter

import { Catch, ExceptionFilter, HttpException, Inject } from "@nestjs/common";
import type { ArgumentsHost } from "@nestjs/common";
import { FastifyReply, FastifyRequest } from "fastify";
import { getReasonPhrase } from "http-status-codes";
import { WINSTON_MODULE_PROVIDER } from "nest-winston";
import { Logger } from "winston";

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
    constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) { }

    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<FastifyReply>();
        const request = ctx.getRequest<FastifyRequest>();
        const status = exception.getStatus();
        const results = exception.getResponse() as any;

        const message = (results.message ?? results) || getReasonPhrase(status)

        // 返回的对象
        const jsonData = {
            code: status,
            message,
            data: null
        };

        // 记录日志      
        this.logger.error(message);

        return response.code(status).send(jsonData);
    }
}
// app.module.ts

// provider
providers: [
AppService,
{
  provide: APP_FILTER,
  useClass: HttpExceptionFilter
},

内置 HTTP 异常类

异常类状态码适用场景
BadRequestException400请求语法错误或无效数据(如参数缺失)。
UnauthorizedException401未授权访问(如缺少 Token)。
ForbiddenException403权限不足(如用户角色不符)。
NotFoundException404资源不存在(如查询 ID 无效)。
MethodNotAllowedException405HTTP 方法不支持(如 POST 接口用 GET 调用)。
NotAcceptableException406请求内容类型不匹配。
RequestTimeoutException408请求超时。
ConflictException409资源冲突(如重复创建用户)。
GoneException410资源已永久删除。
PayloadTooLargeException413请求体过大。
UnsupportedMediaTypeException415不支持的媒体类型(如文件格式错误)。
UnprocessableEntityException422语义错误(如验证失败)。
InternalServerErrorException500服务器内部错误(如数据库连接失败)。
NotImplementedException501功能未实现。
BadGatewayException502网关/代理错误。
ServiceUnavailableException503服务不可用(如维护中)。
GatewayTimeoutException504网关超时。