NestJS 异常过滤器(Exception Filter)与全局错误处理
请解释 NestJS 的异常过滤器(Exception Filter)机制,包括内置异常类(HttpException/BadRequestException)、自定义异常过滤器、以及全局过滤器注册方式。
回答
古法程序员
NestJS 异常处理层级:
控制器 → 拦截器 → 守卫 → 管道 → 异常过滤器(最外层)
1. 内置异常类:
import { HttpException, HttpStatus } from '@nestjs/common';
// 基础
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
// 带自定义响应
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: '无权访问',
timestamp: new Date().toISOString(),
}, HttpStatus.FORBIDDEN);
// 预定义异常
throw new BadRequestException('参数错误');
throw new UnauthorizedException('未登录');
throw new NotFoundException('资源不存在');
throw new ConflictException('数据冲突');
2. 自定义异常过滤器:
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Response } from 'express';
@Catch(HttpException) // 捕获 HttpException 及其子类
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
const exceptionResponse = exception.getResponse();
response.status(status).json({
code: status,
message: typeof exceptionResponse === 'string'
? exceptionResponse
: (exceptionResponse as any).message || '服务器错误',
timestamp: new Date().toISOString(),
path: ctx.getRequest().url,
});
}
}
// 捕获所有异常(包括非 HttpException)
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) { ... }
}
3. 注册方式:
// 全局注册(main.ts)
app.useGlobalFilters(new HttpExceptionFilter());
// 或模块级别注册
@Module({
providers: [{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
}],
})
// 方法/控制器级别
@UseFilters(new HttpExceptionFilter())
最佳实践:全局统一错误格式,区分开发/生产环境的错误详情。