Performance: let MongoDB return errors instead of preventing them

For performance purpose, would it be a bad practice to let mongodb handle the errors instead of trying to avoid them in advance?
A good example is when I want to insert in a “user” collection that has a unique index on the key “email” a new document. The “standard” flow, would be to:

  • firstly we check if a document already exists with this email
  • if so , we throw an error
  • else we save the new document

So basically, it’s 2 calls to MongoDB, one for the check and one for the insertion. But couldn’t I use the returned error from the index so I can do only one call to MongoDB?

  • Directly saves the document
  • if the duplicate key error is returned, we throw an error “Email already exists”

So here there is no need for the previous check, we only have one call to MongoDB !
Is it something I can do or is it bad practice?

For the example, in node.js and mongoose it would be something like the folllowing:

Standard flow with check first:

try {
  checkUser = await Users.findOne({ email: newUser.email).exec()
  if (checkUser) throw new Error("User already exists")
  else insertedUser = await new User({ newUser }).save()
} catch(error) { 
  throw (error) 
}

Direct flow handling returned error has a check:

try {  
  await new User({ newUser }).save() 
}
catch(error) { 
 if (error.code == "11000" and error.keyValue == "{ email: ${newUser.email }}"
 throw new Error("User already exists")
}

With this last example, we understand that with the list of all mongodb errors we could handle a lot of returned errors instead of checking firstly ourselves. I have a file that lists all errors but as e new user in the forum I can’t attach it. If you are interested I could find a way to send this…

1 Like

Hello @Thomas_Perrin, welcome to the MongoDB Community forum!

I think the single call to the database is the correct way to handle the above functionality.

Here is what I had tried (this is using native MongoDB NodeJS Driver API):

try {
	insertResult = await collection.insertOne(doc)
}
catch(err) {
	if (err instanceof MongoServerError && err.code === 11000) {
		console.error("# Duplicate Data Found:\n", err)
		insertResult = { 
			insertedId: null,
			message: "Message expalining the situation."
		}
	}
	else {
		throw new Error(err)
	}
}

The MongoDB NodeJS Driver Error classes has MongoServerError as one of its sub-classes. The "E11000 duplicate key error collection" is defined as one of the errors as MongoServerError.

Also see:

1 Like

Welcome to the MongoDB Community Forums @Thomas_Perrin!

To provide some further context to @Prasad_Saya’s answer: the approach with two queries adds latency (one extra round trip) without improving the outcome: a conflicting value could be inserted by another client in between the initial query and the insert, so you still have to handle the possibility of a duplicate key exception.

Regards,
Stennie

2 Likes

Ok thanks a lot for you responses @Prasad_Saya and @Stennie. I will have a close look to your mongodb error handling links. Cheers!

Hey @Prasad_Saya , I tried to add the “err instanceof MongoServerError” check as yours, but I got the error “MongoServerError is not defined” (I also tried with MongoError since I am on mongoose v5). Where did you require MongoServerError from?
Thanks !

See the MongoDB NodeJS Driver - Installation.

Ok I see, but I work only with mongoose to reach a remote Atlas MongoDB server, so I don’t have the local mongodb npm package installed. Wouldn’t it be a little to much to install a local mongdb server just to get this error object. Is there a way to do so without installing a full local mongodb server?

No, you dont need to install the full local mongodb server - it is the driver software you need to install. Please follow the instructions for installing MongoDB NodeJS Driver from my previous link.

Okk, sorry I didn’t understand it was only a druver… So I installed it through npm, I know have both Mondob NodeJS Driver and mongoose installed (I hope there won’t be any conflict but at the moment all my tests pssed!). But even with the driver installed, I stiull have the error “MongoServerError is not defined”. I found a require on the net const MongoServerError = require("mongodb-core").MongoServerError; but when called I still have “MongoServerError is undefined”. Do you know if I should require it in an other way?
I followed the installation instructions but after that not the “starts a server” instructions, since I connect to a remote Atlas server.
Thanks a lot for your concern

Hi @Thomas_Perrin,

What version of Mongoose are you using? Mongoose depends on the MongoDB Node.js driver, so you should not have to install this separately.

I expect you are using a version of Mongoose which is not the latest release series (currently 6.x). Mongoose 6.x depends on the 4.x MongoDB Node.js driver in which MongoError is now MongoServerError.

I expect you can change the reference in @Prasad_Saya’s code example to MongoError if you are using an older version of Mongoose, but I would advise upgrading to the current version of Mongoose if you are starting a new project.

I also suggest including some context like your versions of Mongoose, Node.js, and MongoDB server when starting new discussions. Extra details will help the community provide more relevant recommendations faster :slight_smile:

Regards,
Stennie

This is how I use:

const { MongoServerError } = require("mongodb")

Ok thank a lot to both of you, indeed it was a version problem and it works well with const { MongoError } = require("mongodb") since I run mongoose v4. Indeed it still works with mongodb driver npm uninstalled and so only using mongoose.

I will keep in mind to give versions for my next topics!

Thanks again, Thomas

1 Like

Hi @Thomas_Perrin,

Mongoose 4.x is designed for older versions of MongoDB server (3.4.x at best) which have all been End Of Life (EOL) for several years: Mongoose => MongoDB Server Version Compatibility.

I strongly recommend upgrading to modern (and non-EOL) software versions, particularly if you’d like community assistance for troubleshooting.

Regards,
Stennie

Nope sorry it was express v4 but mongoose v5 ! Thanks

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.