Skip to content
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

multiple validator errors #1214

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 18 additions & 7 deletions lib/errors/validator.js
Expand Up @@ -8,28 +8,39 @@ var MongooseError = require('../error');
* Schema validator error
*
* @param {String} path
* @param {String} msg
* @param {String|Array} type or array of validator errors
* @inherits MongooseError
* @api private
*/

function ValidatorError (path, type) {
var msg = type
? '"' + type + '" '
: '';
MongooseError.call(this, 'Validator ' + msg + 'failed for path ' + path);
if (Array.isArray(type)) {
this.errors = type;
MongooseError.call(this, 'Validators failed for path ' + path);
} else {
var msg = type
? '"' + type + '" '
: '';
MongooseError.call(this, 'Validator ' + msg + 'failed for path ' + path);
this.type = type;
};
Error.captureStackTrace(this, arguments.callee);
this.name = 'ValidatorError';
this.path = path;
this.type = type;
};

/*!
* toString helper
*/

ValidatorError.prototype.toString = function () {
return this.message;
if (this.errors) {
return this.name + ': ' + this.errors.map(function (value) {
return String(value);
}, this).join(', ');
} else {
return this.message;
}
}

/*!
Expand Down
31 changes: 22 additions & 9 deletions lib/schematype.js
Expand Up @@ -541,20 +541,33 @@ SchemaType.prototype.select = function select (val) {
*/

SchemaType.prototype.doValidate = function (value, fn, scope) {
var err = false
var err = null
, path = this.path
, count = this.validators.length;

if (!count) return fn(null);
if (!count) return fn(err);

function validate (val, msg) {
if (err) return;
if (val === undefined || val) {
--count || fn(null);
} else {
fn(err = new ValidatorError(path, msg));
}
}
--count;
if (val !== undefined && !val) {
if (err && !Array.isArray(err)) {
var errArray = [err];
err = errArray;
} else if (!err) {
err = new ValidatorError(path, msg);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ValidatorError should always be returned regardless of number of errors. We should probably just modify it to accept multiple errors instead of creating a new type.

};
if (Array.isArray(err)) {
err.push(new ValidatorError(path, msg));
};
};
if (!count) {
if (Array.isArray(err)) {
return fn(new ValidatorError(path, err));
} else {
return fn(err);
};
};
};

this.validators.forEach(function (v) {
var validator = v[0]
Expand Down
16 changes: 16 additions & 0 deletions test/schema.test.js
Expand Up @@ -465,6 +465,22 @@ describe('schema', function(){
done();
});

it('multiple errors', function(done){
var MultipleTest = new Schema({
testProperty: { type: Number, required: true, min: 1, max: 5 }
});

MultipleTest.path('testProperty').doValidate(undefined, function (err) {
assert.ok(err instanceof ValidatorError);
assert.equal(true, Array.isArray(err.errors));
assert.equal(err.errors.length, 3);
for (var i = 0; i < err.errors.length; i += 1) {
assert.ok(err.errors[i] instanceof ValidatorError);
};
done();
});
});

describe('async', function(){
it('works', function(done){
var executed = 0;
Expand Down