本文介绍了无法捕获knex交易拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照此问题的建议使用具有异步/等待语法的knex事务:

I'm using knex transaction with async/await syntax as suggested in this question: Get Knex.js transactions working with ES7 async/await

我的问题是,当事务失败并调用trx回调时,knex日志

My problem is, that when transaction fails and trx callback is invoked, knex logs

与记录器记录的错误相同,因此记录如下所示:

just under the same error logged by logger, so logs looks like that:

// Removed error stacks...

// Error logged by logger
2019-07-14T23:12:29.606Z [error]: error: insert into "tab1" ("col1", "col2", "col3") values ($1, $2, $3) returning "col3" - relation "tab1" does not exist

// Koa.js error from ctx.throw()
InternalServerError: Internal Server Error

// Error when invoking await trx.rollback(e)
Unhandled rejection error: relation "tab1" does not exist

我要达到的目标是调用trx.rollback(e)而不引发未处理的拒绝错误.

What I want to achive is to call trx.rollback(e) without throwing unhandled rejection error.

以及导致此问题的代码:

And the code causing this problem:

async function create (ctx) {
  const trx = await tools.promisify(knex.transaction.bind(knex))
  try {
    let [var1] = await trx('tab1').insert({...}).returning(['x', 'y'])

    // tab2 doesn't exist to trigger an error
    const [var2] = await trx('tab2').insert({...}).returning('z')

    await trx.commit()
  } catch (e) {
    await trx.rollback(e)
    logger.error(e)
    ctx.throw()
  }
}

推荐答案

您使用的交易错误...请尝试以下操作:

You are using transactions wrong... try this:

async function create (ctx) {
  try {
    const res = await knex.transaction(async trx => {
      let [var1] = await trx('tab1').insert({...}).returning(['x', 'y'])
      // tab2 doesn't exist to trigger an error
      const [var2] = await trx('tab2').insert({...}).returning('z')

      return [var1, var2];
    });
  } catch (e) {
    logger.error(e)
    ctx.throw()
  }
}

如果您真的想要,也可以使用最新的knex 0.18和transactionProvider() ...可以从knex文档中找到...但是在您的情况下,第一种方法的效果更好,并且比显式提交更可靠.

Also if you really want you can use latest knex 0.18 and transactionProvider()... it is found from knex docuementation... but in your case 1st way works even better and will be more robust that explicit commit.

您问题的真正答案是:

trx = await tools.promisify(knex.transaction.bind(knex))

不将任何处理程序绑定到knex.transaction(trx => {...})调用返回的承诺链,然后在您调用.rollback(e)时,该链拒绝并泄漏该异常.

doesn't bind any handlers to promise chain returned by knex.transaction(trx => {...}) call and then when you call .rollback(e) that chain rejects and leaks that exception.

这篇关于无法捕获knex交易拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 20:40