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

NestJS控制器中如何检测服务空返回结果并抛出异常

问题原因

服务层的getPreferences是异步函数,返回值为Promise类型。你在控制器中调用该方法时没有加await等待异步执行完成,此时拿到的永远是pending状态的Promise实例,不管数据库实际返回空还是有值,都无法通过直接判断变量拿到真实结果。另外你原来的判断条件写反了:有结果时不应该抛异常,只有返回空值时才需要触发404。

正确实现方式

第一步:修改服务层代码

既然要把异常抛出逻辑迁移到控制器,服务层就不再保留非空校验,直接返回数据库查询结果即可,同时补全返回值类型:

async getPreferences(eUserId: string): Promise<UserPreferences | null> {
  return this.userPreferencesModel.findOne({
    eUserId,
  });
}

返回值类型加| null是因为Mongoose的findOne方法查不到匹配数据时会返回null,类型定义需要和实际返回逻辑一致。

第二步:修改控制器代码

调用服务层方法时添加await关键字,等待异步查询完成拿到真实返回值后,再做非空判断、抛出异常:

@Get()
async getPreferences(
  @Headers('x-e-user-id') eUserId: string,
): Promise<UserPreferences> {
  // 等待异步执行完成,拿到真实查询结果
  const userPreferences = await this.userPreferencesService.getPreferences(eUserId);

  console.log('userPreferences: ', userPreferences);
  // 结果为空时抛出404异常
  if (!userPreferences) {
    throw new NotFoundException("We couldn't find your user preferences");
  }

  return userPreferences;
}
可选写法

如果你不想用async/await,也可以用Promise链式调用实现相同效果,不过可读性稍差:

@Get()
getPreferences(
  @Headers('x-e-user-id') eUserId: string,
): Promise<UserPreferences> {
  return this.userPreferencesService.getPreferences(eUserId)
    .then(userPreferences => {
      if (!userPreferences) {
        throw new NotFoundException("We couldn't find your user preferences");
      }
      return userPreferences;
    })
}

补充提示:NestJS内置了全局异常过滤器,不管在控制器层还是服务层抛出的HttpException都会被统一捕获、返回标准格式的错误响应。如果服务层的这个方法会被多个控制器或者其他服务复用,把非空判断和异常抛出留在服务层反而能减少重复代码,维护性更好。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:48:22