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

Node.js中Promise被外部try/catch处理,调用.finally仍触发未处理拒绝

问题解析:Promise.finally 触发未处理拒绝异常的原因

核心本质

Promise的finally()、then()、catch()方法都会生成全新的Promise实例,不会修改原Promise的状态或引用。你的代码中,调用promise.finally()后未处理该方法返回的新Promise的拒绝状态,导致Node.js的Promise检测机制捕捉到未处理的拒绝,抛出异常。

代码逐行拆解

  1. foo函数中创建了一个直接被拒绝的原Promise:
    const promise = new Promise((resolve, reject) => {
        reject('my-error');
    });
    
  2. 调用promise.finally()时,会返回一个新Promise。这个新Promise会继承原Promise的拒绝状态(原因仍为my-error),但你没有对这个新Promise做任何错误处理:
    promise.finally(() => {
        console.log('at foo');
    });
    
  3. 你返回的是原Promise,bar函数里的await和try/catch仅处理了原Promise的拒绝,但finally返回的新Promise的拒绝状态完全无人处理,因此触发了UnhandledPromiseRejection异常。

为何换成catch()就正常?

当替换为catch()时:

promise.catch(() => {
    console.log('at foo');
});

catch()方法返回的新Promise会被标记为已解决(resolved)——因为catch已经处理了原拒绝,默认返回一个状态为resolved的Promise(除非你在catch块中主动抛出新错误),自然不存在未处理的拒绝状态,也就不会触发异常。

修复方案

只需返回finally生成的新Promise,让bar中的try/catch一并处理其状态即可:

const foo = () => {
    const promise = new Promise((resolve, reject) => {
        reject('my-error');
    });
    
    // 返回finally创建的新Promise,而非原Promise
    return promise.finally(() => {
        console.log('at foo');
    });
}

此时bar里的await会等待finally返回的新Promise,try/catch会处理它的拒绝状态,未处理拒绝的异常也就消失了。

内容的提问来源于stack exchange,提问作者Mohammed S. Yaseen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:05:29