mongoose: Throw clean error if save() called in parallel on same doc instance
I have seen a few issues closed already regarding the #save() method and swallowing of exceptions. I’ve got this happening at the moment with the latest version in npm (4.4.12). Here’s some code:
const giftcard = new Giftcard({ // new instance of the model
// setting some properties here
});
giftcard.save((err) => {
if (err) throw new Error(err);
// this never happens - the callback is never called
});
I can post a more detailed example if required.
Edit: Also, this happens with the promise interface as well, so giftcard.save().then() has the same result.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 8
- Comments: 61 (13 by maintainers)
Commits related to this issue
- hotfixing/patching Automattic/mongoose#4064 — committed to phobosjs/phobos.js by mtimofiiv 8 years ago
- test(document): repro #4064 — committed to Automattic/mongoose by vkarpov15 8 years ago
@mtimofiiv @cwhenderson20 @dodekeract I have just donated over PayPal to @vkarpov15 (val@karpov.io) for his time helping me debug this issue. If you have been able to get passed this through our findings please send him some dough! 💸 He deserves it! He spent a ton of time with me, even while he was on his mobile phone he was helping!
@vkarpov15 I am experiencing this same issue on version 4.4.20. Attempting to call
saveon my model results in the callback never being called while running the same operation with$__saveworks just fine.I am not overwriting promises and I do not have any pre-save (or otherwise) middleware for the model and using
mongoose.set("debug", true)does not show anything strange. I have also verified that the document I’m attempting to save does pass validation.I have additionally attached a connection error handler to the mongoose instance and no errors are reported.
Example:
For now I will use the private method as I’m not sure of how to proceed otherwise, but if I can give any more information to help with this, please let me know.
Update Similar to @mtimofiiv,
console.log-ing the methods$__saveandsavegive me the actual$__savemethod as defined in model.js and a function calledwrappedPointCut, respectively.Additionally, after modifying my installed version of mongoose (to log when methods are called) and re-running the code, I can see that indeed the
$__savemethod reports that it is being called, while similar logging forsavenever reports.@vkarpov15 and I talked over Google Chat, and we discovered that due to the
validatorlibrary accepting two arguments for most functions, e.g. my case withisEmail(str, options)and @mtimofiiv case withvalidator.isURL(str, options), it thinks that theoptionsobject is the asynchronous callback, which it isn’t a function, so nothing happens and it hangs.No, I am not overwriting the promise - I will endeavour to put together a more reproducable case for you.
@vkarpov15 Thanks for the wonderful library. It’s fantastic.
So, very occasionally I get errors like this:
When this happens, it happens when I call
.save()on a model instance. I have no solid leads as to the cause. The only things I can think of are:usePushEachfor every model..save()to prevent triggering post save hooks, like so:this solved my problem… connect using mongo client… http://mongoosejs.com/docs/connections.html#use-mongo-client
This is a dupe of #4084, see http://mongoosejs.com/docs/validation.html#async-custom-validators and https://github.com/Automattic/mongoose/issues/4084#issuecomment-213456512. Since so many people are getting bit by this, I’m adding a quick workaround.
Thanks @dodekeract , I’ll try your code and see if I can repro. A test case would be very helpful 👍