Javascript 无法捕获knex事务拒绝

Javascript 无法捕获knex事务拒绝,javascript,node.js,error-handling,knex.js,koa,Javascript,Node.js,Error Handling,Knex.js,Koa,我正在使用knex事务,其语法为async/await,如本问题所述: 我的问题是,当事务失败并调用trx回调时,knex会记录日志 未处理的拒绝错误:关系“some_table”不存在//我用于测试的示例错误 与logger记录的错误相同,因此日志如下所示: // Removed error stacks... // Error logged by logger 2019-07-14T23:12:29.606Z [error]: error: insert into "tab1" ("col

我正在使用knex事务,其语法为async/await,如本问题所述:

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

未处理的拒绝错误:关系“some_table”不存在//我用于测试的示例错误

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

// 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),而不抛出未处理的拒绝错误

以及导致此问题的代码:

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()
  }
}

您正在使用错误的事务。。。试试这个:

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文件中发现的。。。但在您的情况下,第1种方式比显式提交工作得更好,也更健壮

你的问题的真正答案是:

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

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

从字面上删除行
ctx.throw()
@James,谢谢您的回复。不幸的是,删除
ctx.throw()
并不能解决问题。您确定要执行回滚吗?我认为该事务从未提交过b/c,它在trx.commit()之前抛出了一个错误。@DovRine是的,在
trx.commit()之前发生了一个错误。
,但是如果我跳过
trx.rollback()
,空闲连接将保留在PostgreSQL server中。@MaksymilianTomczyk:connections,但不是等待提交的事务。插入发生了吗?看起来不是这样。也许您需要获取db连接的句柄,并在错误处理程序中手动关闭它们。不是有trx.abort()之类的吗?(对不起,我已经5年没有使用knex了。)非常感谢,我修改了我的代码,现在错误被正确捕获了。