Knex Transaction with Promises

You need to return a promise from the inner query in order for the outer chain to be chained with that.

You also swallow any errors because you don’t rethrow them – it’s better to use .catch() for this reason because it makes it more clearer what is happening – that is what would happen with normal try-catch statement.

knex.transaction(function(t) {
   return knex('foo')
   .transacting(t)
   .insert({id:"asdfk", username:"barry", email:"[email protected]"})
   .then(function() {
        return knex('foo')
           .where('username','=','bob')
           .update({email:"[email protected]"});
   })
   .then(t.commit)
   .catch(function(e) {
        t.rollback();
        throw e;
   })
})
.then(function() {
 // it worked
})
.catch(function(e) {
 // it failed
});

To understand it better, here’s the synchronous version that is being “emulated”:

try {
    var t = knex.transaction();
    try {
        knex("foo")
            .transacting(t)
            .insert({id:"asdfk", username:"barry", email:"[email protected]"});
        knex("foo")
            .where('username','=','bob')
            .update({email:"[email protected]"});
        t.commit();
    }
    catch (e) {
        t.rollback();
        // As you can see, if you don't rethrow here
        // the outer catch is never triggered
        throw e;
    }
    // It worked
}
catch (e) {
    //It failed
}

Leave a Comment