I'm using this schema with latest npm mongoose:
var schema = new Schema({
_id: Schema.ObjectId,
email: {type: String, required: true, unique: true}
});
If I try to save a email that is already in db, I expect to get a ValidationError
like if a required
field is omitted. However this is not the case, I get a MongoError: E11000 duplicate key error index
.
Which is not a validation error (happens even if I remove the unique:true).
Setting unique: true
creates an unique index in MongoDB. MongoError: E11000 duplicate key error index
is not a Mongoose validation error, it comes from MongoDB.
how can i catch this error?
doc.save(function (err) {
// handle err
})
i tryed it and the error didin't bubbled.
for now i'm using this function to do validation:
/**
* Unique Validation
* @param {Schema} schema The schema to witch validate.
* @param {Model} model The model to perform searches.
* @param {String} field The field name to search for duplicated entries.
* @throws {E11000} Duplicate key.
*/
function uniqueValidator(schema, model, field) {
schema.pre('save', function(next){
var toValidate = {};
toValidate[field] = this[field];
model.findOne(toValidate, field, function(err, res){
if (err) {
next(err);
} else if (res) {
err = new Error('Duplicate key.');
err.code = 'E11000';
next(err);
} else {
next();
}
});
});
}
it's not best practices but is working. i just wanted to know if there was some "cleaner"/best way to do this. thanks.
ps: i'm using updated versions of both mongo and mongoose
check the indexes that exist in your collection to see if the unique index exists.
use yourDatabase
db.yourCollection.getIndexes()
You should see all indexes that exist on your collection. Check to see if your unique index exists.
If it does, something is very wrong.
If it doesn't (more likely), there are probably duplicate values in the collection already which will prevent a unique index from being created. You can check this by adding a listener to your models index
event and checking for errors:
var schema = Schema(..);
var YourModel = mongoose.model('YourModel', schema);
YourModel.on('index', function (err) {
if (err) console.error(err);
})
http://mongoosejs.com/docs/api.html#model_Model.ensureIndexes
http://mongoosejs.com/docs/guide.html#indexes
thanks. that's what heppened, first i added non-unique values, and then changed the code adding unique: true
to them.
sorry for the question, but how do i abort the save operation?
it's still saving on the db.
I don't understand your question.
as there is a duplicate key and it have to be unique, how do i stop the saving operation so it isin't saved, or what alternative should i try?
I think it would be great if the unique error was thrown the same way of other validators.
Mongoose could check if the error code is 11001 (http://www.mongodb.org/about/contributors/error-codes/) and then call something like: doc.invalidate(path, "unique").
I tried doing this with schema.post('save', ...) but it seems that no post handlers are called on error.
sorry, the error was mine.
i dumped the database and started fresh _with_ the unique:true
setting set, the error was thrown in my save operation and the object didn't got saved (the behavior i was expecting).
i'm really sorry for the inconvenience.
For anyone interested, I鈥檝e added a plugin which checks the DB prior to saving and throws a Mongoose validation error if any of your unique constraints will be violated:
https://github.com/blakehaswell/mongoose-unique-validator
I had this issue and it was due to already existing duplicate values in my index (as pointed out in aheckmann's comment on Feb 1, 2013). I was reading from here http://mongoosejs.com/docs/api.html#schematype_SchemaType-required where it mentions the error, but fails to mention about already exiting duplicates preventing the uniques index from being created in the first place. Might be worth updating the doc to mention this too!
Most helpful comment
For anyone interested, I鈥檝e added a plugin which checks the DB prior to saving and throws a Mongoose validation error if any of your unique constraints will be violated:
https://github.com/blakehaswell/mongoose-unique-validator