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

使用Knex 0.15.2回滚事务时遇「Transaction rejected with non-error: undefined」错误

解决Knex 0.15.2事务回滚时的Transaction rejected with non-error: undefined错误

我之前升级Knex版本时也碰到过一模一样的问题,这个错误的核心原因是Knex 0.14+版本对事务回滚的Promise行为做了调整:在0.12.x这类旧版本中,trx.rollback()返回的是一个resolved状态的Promise;但升级到0.14及以上后,trx.rollback()会返回一个rejected状态的Promise,而且如果不传入任何参数,它的拒绝值就是undefined,这直接触发了你看到的错误。

另外你的Commit函数还有个冗余点:Knex的事务方法本身已经返回标准Promise,完全不需要用co和Q.defer来额外包装,这反而增加了错误处理的复杂度。

修复步骤

1. 给rollback()传入错误参数(必做)

调用回滚时,必须传入一个错误对象或自定义信息,这样Promise被拒绝时就会携带有效的错误值,避免undefined的问题:

pTrx.rollback(new Error('事务已主动回滚'))

2. 简化函数逻辑,适配新版本Promise行为

因为trx.rollback()的Promise总是会被rejected(即使回滚操作成功执行),所以我们需要捕获这个reject,让它不影响后续的成功回调。这里用async/await简化代码,逻辑会更清晰:

async function Commit(pTrx, pIsCommit, pCallback) {
  try {
    if (pIsCommit) {
      // 提交事务:成功时Promise处于resolved状态
      await pTrx.commit();
    } else {
      // 回滚事务:即使成功执行,Promise也会rejected,所以需要捕获
      try {
        await pTrx.rollback(new Error('主动触发事务回滚'));
      } catch (rollbackErr) {
        // 回滚已经完成,这里的错误是我们主动传入的,直接忽略即可
      }
    }
    // 不管是提交还是回滚完成,都返回SUCCESS
    pCallback('SUCCESS');
  } catch (error) {
    // 只有真正的异常(比如提交失败)才会走到这里
    pCallback(error);
    console.error('事务处理出错:', error);
  }
}

如果不想用async/await,用原生Promise链式调用也能实现:

function Commit(pTrx, pIsCommit, pCallback) {
  let transactionAction;
  
  if (pIsCommit) {
    transactionAction = pTrx.commit();
  } else {
    // 执行回滚并捕获它的reject,确保后续能进入then逻辑
    transactionAction = pTrx.rollback(new Error('主动回滚')).catch(() => {});
  }

  transactionAction
    .then(() => pCallback('SUCCESS'))
    .catch(error => pCallback(error));
}

这样调整后,代码既适配了Knex 0.15.2的新行为,又简化了冗余的Promise包装逻辑,应该就能解决你遇到的错误了。

内容的提问来源于stack exchange,提问作者M.S.Udhaya Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:20:45