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

未使用await调用抛异常的async函数致Nest.js应用无响应

Nest.js中未await异步函数抛出异常导致服务无响应的解决方案

问题背景

当async函数未使用await调用且抛出异常时,Nest.js应用会进入不再响应请求但进程未终止的状态。部分场景下我们无需等待异步函数完成就返回响应,但多数情况是意外遗漏了await,这会导致服务器失效,排查难度大。

复现代码

app.controller.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('/crash')
  public async crash(): Promise<void> {
    await this.appService.crash();
  }
}

app.service.ts

import { Injectable } from '@nestjs/common';

const sleep = async (ms: number): Promise<void> => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};

const functionThatThrows = async (): Promise<void> => {
  await sleep(2000);
  throw new Error('this will crash the app');
};

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }

  public async crash(): Promise<void> {
    console.log('crashing the app in 3 seconds...');
    await sleep(1000);
    functionThatThrows(); // async function called without await
  }
}

复现步骤

  • 首次调用curl http://localhost:3000/crash,接口正常返回;
  • 再次调用该接口时,服务器无响应,提示:curl: (7) 无法连接到localhost的3000端口,连接耗时5毫秒后失败:拒绝连接

解决方案

1. 全局捕获未处理的Promise拒绝

在Nest.js入口文件(main.ts)中添加Node.js的unhandledRejection事件监听,捕获所有未被处理的Promise异常,避免服务陷入无响应状态:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  // 捕获未处理的Promise拒绝
  process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的Promise异常:', reason);
    // 可根据业务需求添加日志上报、服务重启逻辑
  });
}
bootstrap();

默认情况下,未处理的Promise拒绝会导致Node.js进程状态异常,监听该事件后可以统一处理这类异常,至少保证服务能继续响应后续请求。

2. 手动处理无await异步函数的异常

如果是故意不等待异步函数完成,必须手动捕获其异常,避免未捕获的Promise拒绝:

// 在app.service.ts中修改调用逻辑
functionThatThrows().catch(err => {
  console.error('异步操作异常:', err);
  // 可添加日志、告警等处理
});

3. 开发阶段代码检查(从根源避免)

使用ESLint规则@typescript-eslint/no-floating-promises,该规则会检测所有未被处理的Promise(即没有await、没有返回、没有.catch的异步函数调用),在开发阶段就发现遗漏await的问题。

配置方式:在ESLint配置文件中添加:

{
  "rules": {
    "@typescript-eslint/no-floating-promises": "error"
  }
}

开启后,代码中未处理的Promise调用会直接抛出ESLint错误,强制开发者处理这类异步操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:25:19