Skip to content

Nest 内置了一个异常层 ,负责处理应用程序中所有未处理的异常。

当应用程序代码未处理的异常时,该层会捕获该异常,并自动发送适当的、用户友好的响应。

此操作由内置的全局异常过滤器执行,该过滤器处理 HttpException 类型(及其子类)的异常。

当异常无法识别 (既不是 HttpException 也不是继承自 HttpException 类)时,内置异常过滤器会生成以下默认 JSON 响应:

json
{
  "statusCode": 500,
  "message": "Internal server error"
}

1.HttpException

Nest 中提供了 HttpException 类,该类是 Nest 中所有内置异常的基类。

HttpException 该类由 @nestjs/common 包暴露。

1-1.Throw HTTP exceptions

HttpException 类语法的使用形式如下:

new HttpException(message/JSON, status, options?)

其中,options 支持定义causedescription 属性。

ts
@Get()
async findAll() {
  try {
    await this.service.findAll()
  } catch (error) {
    throw new HttpException({
      status: HttpStatus.FORBIDDEN,
      error: 'This is a custom message',
    }, HttpStatus.FORBIDDEN, {
      cause: error
    });
  }
}

1-2.Built-in HTTP exceptions

Nest 提供了一组继承自基类 HttpException 标准异常。

Built-in HTTP exceptions

  • BadRequestException
  • UnauthorizedException
  • NotFoundException
  • ForbiddenException
  • NotAcceptableException
  • RequestTimeoutException
  • ConflictException
  • GoneException
  • HttpVersionNotSupportedException
  • PayloadTooLargeException
  • UnsupportedMediaTypeException
  • UnprocessableEntityException
  • InternalServerErrorException
  • NotImplementedException
  • ImATeapotException
  • MethodNotAllowedException
  • BadGatewayException
  • ServiceUnavailableException
  • GatewayTimeoutException
  • PreconditionFailedException

2.Custom exceptions

如果需要创建自定义异常,那么需要创建好异常层次结构,其中自定义异常继承自基类 HttpException

通过这种方法,Nest 将识别异常,并自动处理错误响应。

ts
export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}

然后可以直接这样使用它:

ts
@Get()
async findAll() {
  throw new ForbiddenException();
}

3.Exception filters

基础(内置)异常过滤器可以自动处理许多情况,如果希望完全控制异常层,那么可以使用异常过滤器控制精确的控制流以及发送回客户端的响应内容)。

例如,可以添加日志记录或根据某些动态因素使用不同的 JSON 模式:

ts
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,
      });
  }
}

TIP

@Catch(HttpException) 装饰器将所需的元数据绑定到异常过滤器,告知 Nest 此特定过滤器只查找 HttpException 类型的异常。

@Catch() 装饰器可以接受单个参数,也可以接受逗号分隔的列表。