推荐答案
在 Nest.js 中,错误处理主要通过以下几种方式实现:
内置异常过滤器:Nest.js 提供了内置的异常过滤器,可以捕获应用程序中抛出的异常,并将其转换为 HTTP 响应。常见的异常包括
HttpException和BadRequestException等。自定义异常过滤器:通过实现
ExceptionFilter接口,可以创建自定义的异常过滤器,以处理特定的异常类型或自定义异常。全局异常过滤器:可以将自定义异常过滤器注册为全局过滤器,以便在整个应用程序中捕获和处理异常。
使用
@Catch()装饰器:通过@Catch()装饰器,可以指定过滤器捕获的异常类型。使用
@UseFilters()装饰器:可以在控制器或路由处理程序级别应用异常过滤器。日志记录:在异常处理过程中,通常会将错误信息记录到日志中,以便后续分析和调试。
本题详细解读
1. 内置异常过滤器
Nest.js 内置了许多常见的异常类,如 HttpException、BadRequestException、NotFoundException 等。这些异常类可以直接在代码中抛出,Nest.js 会自动捕获并将其转换为相应的 HTTP 响应。
// www.javascriptcn.com code example
import { Controller, Get, NotFoundException } from '@nestjs/common';
@Controller('items')
export class ItemsController {
@Get(':id')
findOne(@Param('id') id: string) {
if (!this.itemsService.exists(id)) {
throw new NotFoundException('Item not found');
}
return this.itemsService.findOne(id);
}
}在上面的例子中,如果 itemsService.exists(id) 返回 false,则会抛出 NotFoundException,Nest.js 会自动将其转换为 404 状态码的 HTTP 响应。
2. 自定义异常过滤器
通过实现 ExceptionFilter 接口,可以创建自定义的异常过滤器。以下是一个自定义异常过滤器的示例:
// www.javascriptcn.com code example
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}在这个例子中,HttpExceptionFilter 捕获所有 HttpException 类型的异常,并返回一个包含错误信息的 JSON 响应。
3. 全局异常过滤器
要将自定义异常过滤器注册为全局过滤器,可以在 main.ts 中使用 app.useGlobalFilters() 方法:
// www.javascriptcn.com code example
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './filters/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();这样,HttpExceptionFilter 将应用于整个应用程序中的所有路由。
4. 使用 @Catch() 装饰器
@Catch() 装饰器用于指定过滤器捕获的异常类型。例如,以下过滤器仅捕获 NotFoundException:
import { ExceptionFilter, Catch, NotFoundException } from '@nestjs/common';
@Catch(NotFoundException)
export class NotFoundExceptionFilter implements ExceptionFilter {
catch(exception: NotFoundException, host: ArgumentsHost) {
// 处理 NotFoundException
}
}5. 使用 @UseFilters() 装饰器
@UseFilters() 装饰器可以在控制器或路由处理程序级别应用异常过滤器。例如:
// www.javascriptcn.com code example
import { Controller, Get, UseFilters, NotFoundException } from '@nestjs/common';
import { NotFoundExceptionFilter } from './filters/not-found-exception.filter';
@Controller('items')
@UseFilters(NotFoundExceptionFilter)
export class ItemsController {
@Get(':id')
findOne(@Param('id') id: string) {
if (!this.itemsService.exists(id)) {
throw new NotFoundException('Item not found');
}
return this.itemsService.findOne(id);
}
}在这个例子中,NotFoundExceptionFilter 仅应用于 ItemsController 中的路由。
6. 日志记录
在异常处理过程中,通常会将错误信息记录到日志中。可以使用 Nest.js 的 Logger 服务来记录日志:
// www.javascriptcn.com code example
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, Logger } from '@nestjs/common';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger(HttpExceptionFilter.name);
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
this.logger.error(`HTTP Exception: ${exception.message}`, exception.stack);
// 其他处理逻辑
}
}在这个例子中,Logger 服务用于记录异常信息和堆栈跟踪。