In the development of my fullstack aplication (which is a facebook clone) i’ve found this error in my server, and i don’t know how to solve it.
I’m using node.js, express, mongodb, mongoose and typescript, and, in the development of the route for liking publications is where this error took place (as well in the liking comments route).
Error
VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"
at generateVersionError (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendnode_modulesmongooselibmodel.js:432:10)
at model.Model.save (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendnode_modulesmongooselibmodel.js:488:28)
at C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendsrccontrollerspublication.ts:166:18
at Generator.next (<anonymous>)
at fulfilled (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendsrccontrollerspublication.ts:5:58)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
version: 10,
modifiedPaths: [ 'likes' ]
}
VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"
at generateVersionError (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendnode_modulesmongooselibmodel.js:432:10)
at model.Model.save (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendnode_modulesmongooselibmodel.js:488:28)
at C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendsrccontrollerspublication.ts:166:18
at Generator.next (<anonymous>)
at fulfilled (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )backendsrccontrollerspublication.ts:5:58)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
version: 10,
modifiedPaths: [ 'likes' ]
}
This only happens when the user in the client side tries to click like button too fast multiple times, so, because of that, the problem doesn’t give the action enough time to interact with the server.
I’ve looked for a solution, and i’ve seen that people mention .update() instead of .save in this cases, but, i can’t really understand specifycally what .update() means and why it might be a solution for this problem.
To give you a litle bit more of context, this is how the logic looks like for the liking pubs route
// Like Publication
export const likePublication = async (req: Request, res: Response) => {
const { publicationId } = req.params;
const { identifier } = req.body;
// Check id's
if (!mongoose.Types.ObjectId.isValid(identifier!))
return res.status(400).json({ Message: "identifier not valid" });
if (!mongoose.Types.ObjectId.isValid(publicationId!))
return res.status(400).json({ Message: "identifier not valid" });
// Find pub
const thePub: Ipub = await Publication.findById(publicationId);
// Find user
const theUser: Iauth = await User.findById(identifier);
try {
// Check if user already liked, if not, like the pub
if (thePub.likes!.find(f => f.identifier === theUser.id) === undefined) {
thePub.likes!.push({ identifier: theUser.id! });
}
// Check if user already liked, if user liked, cut like
else if (thePub.likes!.find(f => f.identifier === theUser.id)) {
thePub.likes = thePub.likes!.filter(
filt => filt.identifier !== theUser.id!
);
}
// Save
await thePub.save();
return res.json(thePub);
} catch (err) {
console.log(err);
return res.status(500).json({ Error: "the API failed" });
}
};
What can i do ? thanks !
2
Answers
Since you control the full-stack, in the frontend part, you can use BlockUI to block the screen when a request is being sent to the server. This will prevent users from doing multiple requests when a request is treated and has not been finished yet.
MongoDB will auto-increment the version number of a document when you save it.
Before the save action, it will compare the version number of the incoming document and the existing document in the collection. If the incoming document version is lower than the version in the collection it will throw the "No matching document found" error. When a user clicks the like button very fast
await Publication.findById(publicationId);
might not return the latest document since the previous save action might not be completed. One way of handling this issue is to set a debounce time in callinglikePublication
route from the frontend. Otherwise, you have to catch this error and try to like again.