使用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
相关产品推荐
相关产品推荐

