node.jsmongodbcatch-block

possible to delete a mongodb catch block


I have updated my mongodb driver which forces me to use two completion blocks: .then() .catch() instead of a single callback. The consequence of this is that any error in my stack down the line will jump back up to the mongodb .catch() and potentially cascade processes all over again. Any 'done' block should only be called once. Code that was once easily traceable and was called only once has lost it's simplicity and coherence when migrating from a single callback to two blocks: then() and catch().

  DB.insertOne(something).then( (r) => 
  {
    done({success:true}); 
  }).catch( (e) => 
  {
    done({success:false, message:e.code});
  });

My question - is it possible to delete the catch block, once the insert command has successfully completed? I want to do this because I do not want the mongodb .catch() block executing when irrelevant and unrelated events crash occur down the line. I am looking for something like this.

  DB.insertOne(something).then( (r) => 
  {
    delete this.catch;//does not work
    done({success:true}); 
  }).catch( (e) => 
  {
    done({success:false, message:e.code});
  });

note also that I do need the catch block in general. I need the catch block to execute once - for example if the insert command were to return an error for attempting to insert the same document with the same ._id (for example).


Solution

  • I see two problems here.

    On one side, if you want to nest promise chains, you can do this:

    DB.insertOne(something)
      .then(r => {
        return Promise.resolve()
          .then(() => processResult(r))
          .then(() => done({success:true}))
          .catch(e => {
              console.log("Error in processResult():", e);
              done({success:false});
          );
      })
      .catch(e => done({success:false})); //only mongo error here 
    

    On the other side, new mongodb client is meant to work with async/await which is widely supported by JavaScript interpreters by now. This avoids using nested promises and is much easier to read and reason about. Here is the usage example:

    import mongo from 'mongodb';
    
    async function main() {
        const client = new mongo.MongoClient('mongodb://localhost:27017', {});
        await client.connect();
        const collection = client.db('test').collection('test');
        try {
            return await collection.insertOne({hello: 'world'});
        } catch (e) {
            console.log("Error inserting",e);
        } finally {
            await client.close();
        }
    }
    
    console.log(await main());
    

    Note, I avoided a try-catch around connect() and close() for clarity, you might need to adjust catching errors to your needs, the syntax is exactly the same as for synchronous code blocks.