Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to check for mongoose validation error

I've got two validation functions for my usermodel

User.schema.path('email').validate(function(value, respond) {   User.findOne({email: value}, function(err, user) {     if(err) throw err;     if(user) return respond(false);     respond(true);   }); }, 'EMAIL_EXISTS'); 

and the same for username

User.schema.path('username').validate(function(value, respond) {   User.findOne({username: value}, function(err, user) {     if(err) throw err;     if(user) return respond(false);     respond(true);   }); }, 'USERNAME_TAKEN'); 

They return errors in the following format

{ message: 'Validation failed',   name: 'ValidationError',   errors:      { username:        { message: 'Validator "USERNAME_TAKEN" failed for path username',         name: 'ValidatorError',         path: 'username',         type: 'USERNAME_TAKEN' } } } 

The error for the email path is similar. Is there a smarter way to check for those errors than the following?

if (err && err.errors && err.errors.username) { ... } 

This is kind of ugly.

like image 955
zemirco Avatar asked Jan 18 '13 20:01

zemirco


People also ask

Does mongoose have built-in validation?

Mongoose has several built-in validators. All SchemaTypes have the built-in required validator. The required validator uses the SchemaType's checkRequired() function to determine if the value satisfies the required validator. Numbers have min and max validators.

What is Mongoose unique validator?

mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema. This makes error handling much easier, since you will get a Mongoose validation error when you attempt to violate a unique constraint, rather than an E11000 error from MongoDB.

What is the need of Mongoose .how it is useful for validation?

Mongoose gives us a set of useful built-in validation rules such: Required validator checks if a property is not empty. Numbers have min and max validators. Strings have enum , match , minlength , and maxlength validators.


2 Answers

Technically you must check first the error name because not all errors are handled the same way. Then, based on the error name you must check for particular properties, as the errors property that comes with a ValidationError.

Also you put the field name in the error type and this is redundant, it's better to use the same error type because in the error checking procedure you will get the field name also.

So your code can be something like:

User.schema.path('email').validate(function(value, respond) {   User.findOne({email: value}, function(err, user) {     if(err) throw err;     if(user) return respond(false);     respond(true);   }); }, 'exists');  User.schema.path('username').validate(function(value, respond) {   User.findOne({username: value}, function(err, user) {     if(err) throw err;     if(user) return respond(false);     respond(true);   }); }, 'exists'); 

And then, the error checking procedure:

if (err) {   switch (err) {     case err instanceof mongoose.Error.ValidationError:       for (field in err.errors) {         switch (err.errors[field].type) {           case 'exists':             ...             break;           case 'invalid':             ...             break;           ...         }       }       break;     default:       ...   } } 

If you want to shorten this, you have various options. If you only have one type of validation you can do it like this:

if (err) {   if (err instanceof mongoose.Error.ValidationError) {     for (field in err.errors) {       ...     }   } else {     // A general error (db, crypto, etc…)     ...   } } 

The minimal expression of the error check procedure would be similar to what you've wrote in your post:

if (err) {   for (field in err.errors) {     ...   } } 

This will work because if errors is not defined it will just ignore the for. But you're ignoring all other error types here.

I also think that these error layouts are a bit messing, but don't expect for this to change in a near future.

like image 90
Sergi Ramón Avatar answered Sep 30 '22 07:09

Sergi Ramón


Just write the following code and enjoy.

if (err) {     console.log('Error Inserting New Data');     if (err.name == 'ValidationError') {         for (field in err.errors) {             console.log(err.errors[field].message);          }     } } 
like image 44
Sudhanshu Gaur Avatar answered Sep 30 '22 07:09

Sudhanshu Gaur