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…
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.
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.
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 !
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
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
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!