最好的方法来检查mongoosevalidation错误
我有两个validation函数为我的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');
和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');
他们以下面的格式返回错误
{ message: 'Validation failed', name: 'ValidationError', errors: { username: { message: 'Validator "USERNAME_TAKEN" failed for path username', name: 'ValidatorError', path: 'username', type: 'USERNAME_TAKEN' } } }
email
path的错误是相似的。 有没有比以下更聪明的方法来检查这些错误?
if (err && err.errors && err.errors.username) { ... }
这有点丑。
从技术上讲,你必须首先检查错误名称,因为不是所有的错误都以相同的方式处理。 然后,基于错误名称,您必须检查特定属性,作为ValidationError附带的错误属性。
此外,您将字段名称放在错误types中,这是多余的,最好使用相同的错误types,因为在错误检查过程中,您也将获得字段名称。
所以你的代码可以是这样的:
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');
然后,错误检查程序:
if (err) { switch (err.name) { case 'ValidationError': for (field in err.errors) { switch (err.errors[field].type) { case 'exists': ... break; case 'invalid': ... break; ... } } break; default: ... } }
如果你想缩短这个,你有各种select。 如果你只有一种types的validation,你可以这样做:
if (err) { if (err.name == 'ValidationError') { for (field in err.errors) { ... } } else { // A general error (db, crypto, etc…) ... } }
错误检查过程的最小expression式与您在文章中所写的内容类似:
if (err) { for (field in err.errors) { ... } }
这将工作,因为如果没有定义错误,它会忽略for。 但是你忽略了所有其他的错误types。
我也认为这些错误的布局有点麻烦,但不要指望在不久的将来会有所改变。
只要写下面的代码,享受。
if (err) { console.log('Error Inserting New Data'); if (err.name == 'ValidationError') { for (field in err.errors) { console.log(err.errors[field].message); } } }
我使用AngularJS,所以ngRepeat
显示我的validation错误的网页表单。 我所需要做的就是返回一组错误消息。
有时Mongoose会抛出一个不是validation错误的错误,在这种情况下,err.errors对象将不会出现。 我logging了执行错误。 我仍然使用Web窗体上的相同位置来向用户显示执行错误。
var makeMongooseErrorMsgArray = function(err){ var msgArray = []; if (err.errors) { // validation errors $.each(err.errors, function (key, val) { msgArray.push(val.message); }); } else if (err.message){ // should be execution error without err.errors errLogr.log(err); // log execution errors msgArray.push(err.message); } else { msgArray.push('Unknown error'); } return msgArray; }
为什么不使用API中描述的validation
方法?
objectToSave.validate(function(err) { if (err) { // handle error } else { // validation passed } });
我发现这有助于显示数组中的所有错误。
例如,我提交了一个短密码和无效电子邮件的表格。
if (err && err.name === 'ValidationError') { err.toString().replace('ValidationError: ', '').split(',') }
这导致了这一点
[ 'Please provide a valid email address', 'The password should be at least 6 characters long' ]
如果你有一个逗号,
在你的错误信息中比不用.split(',')
不需要循环。 确保在模式中有validation错误消息。 对于上面的例子,我有
const validateEmail = email => { const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; return re.test(email); }; const Schema = mongoose.Schema; const userSchema = new Schema({ ... email: { type: String, trim: true, required: 'Email address is required', validate: [validateEmail, 'Please provide a valid email address'], }, password: { type: String, set: encryptPassword, maxlength: [6, 'The password should be at least {MAXLENGTH} characters long'] }, ... });