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

NestJs中Guard内无法抛出UnauthorizedException的问题求助

解决自定义Guard中抛出UnauthorizedException导致应用崩溃的问题

问题出在当前的Promise处理逻辑上:在then回调里抛出的错误没有被外层Promise捕获,导致未处理的异常引发应用崩溃。而resolve(false)能正常工作是因为NestJS会自动将Guard返回的false转换为403的ForbiddenException。

以下是几种可行的修复方案:

方案1:将throw替换为reject

在Promise的回调中,需要通过reject传递错误,而非直接throw,这样NestJS才能正确捕获并处理这个异常:

canActivate(
  context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
  return new Promise((resolve, reject) => {
    const request = context.switchToHttp().getRequest();
    const token = request.headers['token'] as string;
    this.authService
      .getUserFromAuthenticationToken(token, false)
      .then((user) => {
        if (user) resolve(true);
        else reject(new UnauthorizedException()); // 替换为reject
      });
  });
}

方案2:改用async/await语法

使用async/await可以让错误自动被Promise捕获,代码更简洁直观:

async canActivate(context: ExecutionContext): Promise<boolean> {
  const request = context.switchToHttp().getRequest();
  const token = request.headers['token'] as string;
  
  const user = await this.authService.getUserFromAuthenticationToken(token, false);
  if (!user) {
    throw new UnauthorizedException();
  }
  return true;
}

方案3:为then添加catch捕获错误

通过在then链后添加catch,将错误传递给外层Promise的reject:

canActivate(
  context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
  return new Promise((resolve, reject) => {
    const request = context.switchToHttp().getRequest();
    const token = request.headers['token'] as string;
    this.authService
      .getUserFromAuthenticationToken(token, false)
      .then((user) => {
        if (user) resolve(true);
        else throw new UnauthorizedException();
      })
      .catch(reject); // 捕获错误并传递给reject
  });
}

采用以上任意一种方案后,NestJS都会正确处理UnauthorizedException,返回401状态码而非让应用崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:45:20