-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
beautiful mongodb native errors (unique - code 11000) #2284
Comments
+1 By the way, for any unique indexed fields, I have to check whether existent fields exists before creating new doc. This is duplicate work. It would be great that it is auto handled. |
Something like if (11000 === err.code || 11001 === err.code) {
var MongooseError = require('mongoose/lib/error')
var valError = new MongooseError.ValidationError(err)
valError.errors["xxx"] = new MongooseError.ValidatorError('xxx', 'Duplicate found', err.err)
err = valError
} could be triggered after anything is received from a db. So every function like |
Good suggestion, thanks. |
mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema. https://github.com/blakehaswell/mongoose-unique-validator |
@vkarpov15 as of now I have a wrapper over mongoose, adding this. Mongoose-unique-validator is doing it wrong. Pre-save validation is not a real solution here, because only unique index guarantees uniqueness. user A: run pre-save, is the value unique? yes it is. |
Yep mongoose-unique-validator is not at all guaranteed to be unique, at least with multiple processes. The "plugin" tag is a reference to OP's issue about beautifying MongoErrors, which would be a valid plugin use case. |
any progress? |
Nope, but I think you might be able to do this as a plugin... |
@xpepermint I'm doing that by a wrapper around save. No idea what @vkarpov15 means about using a plugin here (?) |
I think the way to implement this would be a small separate module that does something like this: module.exports = function(schema) {
schema.methods.trySave = function(callback) {
this.save(function(error, doc) {
// Handle error logic here and callback();
});
};
}; And then any schema that wants to expose this |
Yes, that's kind of what I'm doing. Persist method, like this: |
Yeah something like that as a standalone plugin would probably be a great idea. I like the general idea but I'm hesitant to put this into the mongoose core because it's a big backwards-breaking change and IMO doesn't really move the needle in terms of the experience of using mongoose. |
I made a plugin based on your recommandations. |
My code is a little bit more versatile, so I stick to it for now, but thanks anyway ;) Or does it support custom messages? |
It does indeed, you just need to set the message as the value of var userSchema = mongoose.Schema({
name: {
type: String,
unique: 'Custom error message'
}
});
userSchema.plugin(require('mongoose-beautiful-unique-validation')); |
Thanks for the plugin :) I'll mark this issue as closed. |
I think it's should be out of the box feature. Or maybe we can use mongoose hooks to handle duplicate error? Like this: schema.post('error', function(err, next) { // it can be moved to plugin
if (err.code === 11000) {
return next(new ValidationError(...));
}
next(err);
});
Model.create({}).catch(function(err) {
if (err instanceof ValidationError) {
...
}
}); |
Yeah |
|
That would be tricky, because |
We also should be able to handle model save errors (after |
Where can I find a list of Mongodb error codes? |
Add support for express-style error handling middleware
@vkarpov15 anything changed here? |
I upgraded to Mongoose 4.5.0 and mongo 3.2.7. I tried implementing the following post save hook but it is not working. The err object is not an error object but still the doc object.
It looks like the post save is getting unit tested against here. I am triggering an 11000 mongo error but violating a unique index. |
@VtoCorleone you need to define the |
@vkarpov15 as I recall this issue was about better handling of unique errors, to put them in line with regular validation errors. May I ask, was anything changed here? |
After I learned about these changes I tried to figure out how to use this feature to handle 11000 errors. If I understood correctly I should implement post hooks for all write methods: Additionally I had a question about |
@Jokero yeah that's the general idea, youd also need one for insertMany. IMO it's the solution that adds the least surface area to the api - if you use mongoose, you know how to use hooks, so here's a slight modification to hooks to let you process errors |
@vkarpov15 Does mongodb native errors have beautiful handling now? |
Nope but you can write a plugin to do so pretty easily: http://thecodebarbarian.com/mongoose-error-handling.html |
I created one that I expect to grow to handle most common MongoErrors, this one is using the 4.5 middlewares. https://github.com/jhenriquez/mongoose-mongodb-errors |
I strongly recommend everyone to use the well-documented package by @matteodelabre at https://github.com/matteodelabre/mongoose-beautiful-unique-validation per my PR here matteodelabre/mongoose-beautiful-unique-validation#40. It is well-tested too and also supports a custom message formatted which builds on top of Mongoose standard error messages, e.g. Furthermore, you can also use my new package Here's how to get started with both of these awesome packages: npm install --save mongoose-beautiful-unique-validation mongoose-validation-error-transform const mongooseBeautifulUniqueValidation = require('mongoose-beautiful-unique-validation');
const mongooseValidationErrorTransform = require('mongoose-validation-error-transform');
mongoose.plugin(mongooseBeautifulUniqueValidation);
mongoose.plugin(mongooseValidationErrorTransform); For example, it will take a message of If you wish to customize how the messages are joined, you can provide your own transformation (e.g. you may want to return an mongoose.plugin(mongooseValidationErrorTransform, {
// change this however you like, this is the default:
transform: function(messages) {
return messages.join(', ');
}
}); To output a mongoose.plugin(mongooseValidationErrorTransform, {
// output a <ul> with bootstrap alpha 4 css classes
transform: function(messages) {
if (messages.length === 1) return messages[0];
return `<ul class="text-xs-left mb-0"><li>${messages.join('</li><li>')}</li></ul>`;
}
}); Complete default options for {
capitalize: true,
humanize: true,
transform: function(messages) {
return messages.join(', ');
}
} |
I really miss a mechanism that would create validator-like
unique index
error message. Setting the index of an attribute tounique: true
will tell mongodb to return ugly error message like this:This message should be treated as validator error message thus we could easily display error messages on a REST service.
The text was updated successfully, but these errors were encountered: