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);
}
}
providers: [
AppService,
{
provide: APP_FILTER,
useClass: HttpExceptionFilter
},
内置 HTTP 异常类
| 异常类 | 状态码 | 适用场景 |
|---|
BadRequestException | 400 | 请求语法错误或无效数据(如参数缺失)。 |
UnauthorizedException | 401 | 未授权访问(如缺少 Token)。 |
ForbiddenException | 403 | 权限不足(如用户角色不符)。 |
NotFoundException | 404 | 资源不存在(如查询 ID 无效)。 |
MethodNotAllowedException | 405 | HTTP 方法不支持(如 POST 接口用 GET 调用)。 |
NotAcceptableException | 406 | 请求内容类型不匹配。 |
RequestTimeoutException | 408 | 请求超时。 |
ConflictException | 409 | 资源冲突(如重复创建用户)。 |
GoneException | 410 | 资源已永久删除。 |
PayloadTooLargeException | 413 | 请求体过大。 |
UnsupportedMediaTypeException | 415 | 不支持的媒体类型(如文件格式错误)。 |
UnprocessableEntityException | 422 | 语义错误(如验证失败)。 |
InternalServerErrorException | 500 | 服务器内部错误(如数据库连接失败)。 |
NotImplementedException | 501 | 功能未实现。 |
BadGatewayException | 502 | 网关/代理错误。 |
ServiceUnavailableException | 503 | 服务不可用(如维护中)。 |
GatewayTimeoutException | 504 | 网关超时。 |