ValidationError instead Error

This commit is contained in:
Anatoliy Chakkaev 2013-04-04 19:31:07 +04:00
parent da5d81f0fa
commit 3a355851b6
3 changed files with 55 additions and 11 deletions

View File

@ -4,7 +4,9 @@
var util = require('util'); var util = require('util');
var i8n = require('inflection'); var i8n = require('inflection');
var jutil = require('./jutil.js'); var jutil = require('./jutil.js');
var Validatable = require('./validations.js').Validatable; var validations = require('./validations.js');
var Validatable = validations.Validatable;
var ValidationError = validations.ValidationError;
var List = require('./list.js'); var List = require('./list.js');
var Hookable = require('./hooks.js').Hookable; var Hookable = require('./hooks.js').Hookable;
var DEFAULT_CACHE_LIMIT = 1000; var DEFAULT_CACHE_LIMIT = 1000;
@ -214,7 +216,7 @@ AbstractClass.create = function (data, callback) {
if (valid) { if (valid) {
create(); create();
} else { } else {
callback(new Error('Validation error'), obj); callback(new ValidationError(obj), obj);
} }
}, data); }, data);
@ -657,7 +659,7 @@ AbstractClass.prototype.save = function (options, callback) {
if (valid) { if (valid) {
save(); save();
} else { } else {
var err = new Error('Validation error'); var err = new ValidationError(inst);
// throws option is dangerous for async usage // throws option is dangerous for async usage
if (options.throws) { if (options.throws) {
throw err; throw err;
@ -810,7 +812,7 @@ AbstractClass.prototype.updateAttributes = function updateAttributes(data, cb) {
inst.isValid(function (valid) { inst.isValid(function (valid) {
if (!valid) { if (!valid) {
if (cb) { if (cb) {
cb(new Error('Validation error'), inst); cb(new ValidationError(inst), inst);
} }
} else { } else {
inst.trigger('save', function (saveDone) { inst.trigger('save', function (saveDone) {

View File

@ -1,4 +1,5 @@
exports.Validatable = Validatable; exports.Validatable = Validatable;
exports.ValidationError = ValidationError;
/** /**
* Validation encapsulated in this abstract class. * Validation encapsulated in this abstract class.
@ -432,7 +433,7 @@ function validationFailed(inst, v, cb) {
validatorArguments.push(attr); validatorArguments.push(attr);
validatorArguments.push(conf); validatorArguments.push(conf);
validatorArguments.push(function onerror(kind) { validatorArguments.push(function onerror(kind) {
var message; var message, code = conf.validation;
if (conf.message) { if (conf.message) {
message = conf.message; message = conf.message;
} }
@ -443,6 +444,7 @@ function validationFailed(inst, v, cb) {
message = 'is invalid'; message = 'is invalid';
} }
if (kind) { if (kind) {
code += '.' + kind;
if (message[kind]) { if (message[kind]) {
// get deeper // get deeper
message = message[kind]; message = message[kind];
@ -452,7 +454,7 @@ function validationFailed(inst, v, cb) {
message = 'is invalid'; message = 'is invalid';
} }
} }
inst.errors.add(attr, message); inst.errors.add(attr, message, code);
fail = true; fail = true;
}); });
if (cb) { if (cb) {
@ -562,13 +564,39 @@ function configure(cls, validation, args, opts) {
} }
function Errors() { function Errors() {
Object.defineProperty(this, 'codes', {
enumerable: false,
configurable: true,
value: {}
});
} }
Errors.prototype.add = function (field, message) { Errors.prototype.add = function (field, message, code) {
code = code || 'invalid';
if (!this[field]) { if (!this[field]) {
this[field] = [message]; this[field] = [];
} else { this.codes[field] = [];
this[field].push(message);
} }
this[field].push(message);
this.codes[field].push(code);
}; };
function ErrorCodes(messages) {
var c = this;
Object.keys(messages).forEach(function(field) {
c[field] = messages[field].codes;
});
}
function ValidationError(obj) {
if (!(this instanceof ValidationError)) return new ValidationError(obj);
this.name = 'ValidationError';
this.message = 'Validation error';
this.statusCode = 400;
this.codes = obj.errors && obj.errors.codes;
Error.call(this);
};
ValidationError.prototype.__proto__ = Error.prototype;

View File

@ -1,4 +1,5 @@
var j = require('../'), db, User; var j = require('../'), db, User;
var ValidationError = require('../lib/validations.js').ValidationError;
var should = require('should'); var should = require('should');
function getValidAttributes() { function getValidAttributes() {
@ -63,8 +64,9 @@ describe('validations', function() {
describe('lifecycle', function() { describe('lifecycle', function() {
it('should work on create', function(done) { it('should work on create', function(done) {
delete User._validations;
User.validatesPresenceOf('name'); User.validatesPresenceOf('name');
User.create(function(e) { User.create(function(e, u) {
should.exist(e); should.exist(e);
User.create({name: 'Valid'}, function(e, d) { User.create({name: 'Valid'}, function(e, d) {
should.not.exist(e); should.not.exist(e);
@ -74,11 +76,13 @@ describe('validations', function() {
}); });
it('should work on update', function(done) { it('should work on update', function(done) {
delete User._validations;
User.validatesPresenceOf('name'); User.validatesPresenceOf('name');
User.create({name: 'Valid'}, function(e, d) { User.create({name: 'Valid'}, function(e, d) {
d.updateAttribute('name', null, function(e) { d.updateAttribute('name', null, function(e) {
should.exist(e); should.exist(e);
e.should.be.instanceOf(Error); e.should.be.instanceOf(Error);
e.should.be.instanceOf(ValidationError);
d.updateAttribute('name', 'Vasiliy', function(e) { d.updateAttribute('name', 'Vasiliy', function(e) {
should.not.exist(e); should.not.exist(e);
done(); done();
@ -87,6 +91,16 @@ describe('validations', function() {
}); });
}); });
it('should return error code', function(done) {
delete User._validations;
User.validatesPresenceOf('name');
User.create(function(e, u) {
should.exist(e);
e.codes.name.should.eql(['presence']);
done();
});
});
}); });
}); });