Nestjs项目实战 异常处理与全局异常过滤器
在Nestjs项目中,如何优雅地实现全局异常处理?我在使用内置的HttpException时发现无法满足自定义错误格式的需求,尝试创建全局过滤器但遇到以下问题:1. 继承自BaseExceptionFilter的过滤器无法正确处理非HTTP异常;2.在不同模块中抛出的业务异常如何统一格式返回客户端?3.如何在过滤器中区分生产环境和开发环境的错误响应?4.对第三方库抛出的非标准异常该如何封装?希望有实战经验的朋友能分享具体实现方案和最佳实践。
3 回复
在NestJS中,异常处理和全局异常过滤器是非常重要的功能。首先,创建一个自定义异常过滤器,实现ExceptionFilter
接口。例如:
@Injectable()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
console.error(exception);
response.status(500).json({
statusCode: 500,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
然后,在模块中注册该过滤器为全局过滤器:
@Module({
providers: [
{
provide: APP_FILTER,
useClass: AllExceptionsFilter,
},
],
})
export class AppModule {}
这样,所有未捕获的异常都会被这个过滤器捕获并返回统一的错误响应。如果需要针对特定类型的异常进行特殊处理,可以在过滤器中添加条件判断。此外,还可以通过@Catch()
装饰器来指定要捕获的具体异常类型。
NestJS项目实战:异常处理与全局异常过滤器
在NestJS中,异常处理是一个重要环节,良好的异常处理可以提升应用的健壮性和可维护性。
基础异常类
NestJS内置了HttpException
类,我们可以直接使用或继承它:
throw new HttpException('资源不存在', HttpStatus.NOT_FOUND);
自定义异常
可以创建自己的异常类:
export class BusinessException extends HttpException {
constructor(message: string, code: number) {
super({ message, code }, HttpStatus.BAD_REQUEST);
}
}
全局异常过滤器
创建全局异常过滤器是推荐做法:
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
let status = 500;
let message = 'Internal server error';
let errorCode = 'INTERNAL_ERROR';
if (exception instanceof HttpException) {
status = exception.getStatus();
const exceptionResponse = exception.getResponse();
if (typeof exceptionResponse === 'object') {
message = exceptionResponse['message'] || message;
errorCode = exceptionResponse['errorCode'] || errorCode;
} else {
message = exceptionResponse;
}
}
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message,
errorCode
});
}
}
注册全局过滤器
在main.ts
中注册:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new GlobalExceptionFilter());
await app.listen(3000);
}
bootstrap();
业务层异常处理
在服务层抛出业务异常:
async findOne(id: number) {
const user = await this.userRepository.findOne(id);
if (!user) {
throw new BusinessException('用户不存在', 'USER_NOT_FOUND');
}
return user;
}
这样构建的异常处理系统可以提供统一的错误响应格式,便于前端处理和后端调试。