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

嵌套函数中Promise rejection如何捕获 避免Node.js报unhandledRejection错误

问题原因

你遇到的unhandledRejection报错核心有两个:

  1. async 函数的try/catch只能捕获被await的Promise抛出的错误,你当前代码注释了await promise的逻辑,Promise reject的错误无法被外层try/catch捕获。
  2. 你当前的try块只包裹了同步执行的waitBy(3000)调用,这个调用只会同步返回包含promise和cancel的对象,不会抛出任何错误,所以现有写的catch逻辑永远不会触发。
    没有被任何错误处理逻辑捕获的Promise reject,就会被Node.js判定为未处理的拒绝,默认会直接终止进程。

解决方案

如果要让错误正常冒泡到main函数的catch块,只需要把await promise移入同一个try块内即可,修正后的代码如下:

const wait = (timeoutMs: number) => {
  let timeoutHandle: number | undefined;

  const promise = new Promise((_resolve, reject) => {
    timeoutHandle = setTimeout(() => {
      reject(`wait timed out after ${timeoutMs} ms`);
    }, timeoutMs);
  });

  return {
    promise,
    cancel: (): void => clearTimeout(timeoutHandle)
  };
};

const waitBy = (timeoutMs: number) => {
  const res = wait(timeoutMs);
  return res;
};

const main = async () => {
  try {
    const { promise, cancel } = waitBy(3000);
    // 新增await逻辑,放在同一个try块内
    await promise;
  } catch (error) {
    console.log("timed out", error);
  }
};

main();

特殊场景兼容

如果你需要先拿到cancel句柄做其他操作,暂时不需要等待Promise结果,可以临时给Promise挂载一个空的catch回调避免报错,等需要的时候再await原Promise即可,写法如下:

const main = async () => {
  try {
    const { promise, cancel } = waitBy(3000);
    // 临时挂载catch避免未处理拒绝报错,不会影响后续await的错误捕获
    promise.catch(() => {});

    // 这里可以放其他逻辑,比如3秒内调用cancel就可以取消超时
    // cancel()

    await promise;
  } catch (error) {
    console.log("timed out", error);
  }
};

注意这种写法只是临时兜底避免进程崩溃,最终错误还是会被await后的try/catch正常捕获,不会丢失错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:45:01