You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中控制器如何捕获服务抛出的错误及代码优化咨询

问题解答

1. 控制器捕获嵌套函数错误的正确方式

NestJS处理服务层抛出的错误,核心要避免手动响应(@Res())与异常抛出冲突,两种可行方案:

方案一:依赖NestJS内置异常过滤器(推荐)

移除@Res(),让NestJS自动接管响应处理。此时抛出的HttpException会被内置过滤器捕获,自动返回对应状态码和响应体,无需手动处理响应对象。

方案二:全程手动处理响应(适配现有代码)

如果坚持使用@Res(),所有错误分支都通过response返回结果,不要抛出异常。因为用@Res()后,NestJS会放弃对响应的自动管理,抛出的异常会变成未捕获的Promise错误,导致应用崩溃。

2. 解决返回200、控制台报错并终止应用的问题

你的代码问题出在:catch分支中部分逻辑抛出HttpException,但因使用了@Res(),NestJS无法处理这些抛出的异常,最终导致未捕获的Promise rejection,应用终止;同时错误分支的响应未正确发送,客户端收到默认的200状态码。

修复方式(二选一)

方式1:移除@Res(),让NestJS自动处理

修改控制器代码,去掉@Res()参数,直接返回数据或抛出异常:

@Put()
async handleFriendRequest(
  @Body() handleFriendRequestDto: HandleFriendRequestDto,
) {
  try {
    const friendRequestToHandle = await this.friendRequestService.handleFriendRequest(handleFriendRequestDto);
    return {
      message: 'Friend Request has been successfully handled',
      friendRequestToHandle,
    };
  } catch (error) {
    if (error instanceof SenderNotFoundException) {
      throw new HttpException(
        {
          status: HttpStatus.NOT_FOUND,
          code: 'USER_SENDER_NOT_FOUND',
          error: 'User sender not found',
          message: `We could not find the user sender with id ${error.id}`, // 注意用反引号解析变量
        },
        HttpStatus.NOT_FOUND,
        { cause: error },
      );
    } else if (error instanceof FriendRequestNotFoundException) {
      throw new HttpException(
        {
          status: HttpStatus.NOT_FOUND,
          code: 'FRIEND_REQUEST_NOT_FOUND',
          error: 'Friend Request not found',
          message: `We could not find the friend request with id ${error.id}`,
        },
        HttpStatus.NOT_FOUND,
        { cause: error },
      );
    } else if (error instanceof ReceiverNotFoundException) {
      throw new HttpException(
        {
          status: HttpStatus.NOT_FOUND,
          code: 'USER_RECEIVER_NOT_FOUND',
          error: 'User receiver not found',
          message: `We could not find the user receiver with id ${error.id}`,
        },
        HttpStatus.NOT_FOUND,
        { cause: error },
      );
    } else if (error instanceof UserAlreadyFriendException) {
      throw new HttpException(
        {
          status: HttpStatus.BAD_REQUEST,
          code: 'USER_ALREADY_FRIEND',
          error: 'User receiver is already a friend',
          message: 'User receiver is already a friend',
        },
        HttpStatus.BAD_REQUEST,
        { cause: error },
      );
    } else {
      throw new HttpException(
        { message: 'We could not add the user' },
        HttpStatus.BAD_REQUEST,
        { cause: error },
      );
    }
  }
}

方式2:保留@Res(),全程手动返回响应

将所有throw new HttpException替换为response.status().json(),确保每个分支都有明确的响应输出:

if (error instanceof SenderNotFoundException) {
  return response.status(HttpStatus.NOT_FOUND).json({
    status: HttpStatus.NOT_FOUND,
    code: 'USER_SENDER_NOT_FOUND',
    error: 'User sender not found',
    message: `We could not find the user sender with id ${error.id}`,
  });
}
// 其他异常分支同理,全部改为手动返回响应

3. 控制器调用多层嵌套函数是否合理

完全合理。控制器的职责应聚焦于请求接收、参数校验、调用服务层、返回响应,复杂业务逻辑拆分到服务层的多个函数中(比如handleFriendRequest处理请求流转,addAFriend处理核心添加逻辑),符合NestJS分层架构的设计理念,能提升代码的可维护性和可测试性。


内容的提问来源于stack exchange,提问作者DonaPaulsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:53:16