I'm using knex transaction with async/await syntax as suggested in this question: Get Knex.js transactions working with ES7 async/await
My problem is, that when transaction fails and trx callback is invoked, knex logs
Unhandled rejection error: relation "some_table" doesn't exist // Example error which I used for testing
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
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:
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.Real answer to your question is that the line:
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.