不要怂,就是干,撸起袖子干!

Commit 69c06f29 by Sushant Committed by GitHub

Fix #3899 no value in built-in/custom validation errors (#6944)

* fix: no value in built-in/custom validator

* using call rather than bind

* [ci skip] changelog
1 parent 7d597efb
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
- [ADDED] Support condition objects in utility functions [#6685](https://github.com/sequelize/sequelize/pull/6685) - [ADDED] Support condition objects in utility functions [#6685](https://github.com/sequelize/sequelize/pull/6685)
- [FIXED] HSTORE and JSON fields being renamed when `options.field` is specified on a matching model attribute - [FIXED] HSTORE and JSON fields being renamed when `options.field` is specified on a matching model attribute
- [FIXED] Soft-delete not returning number of affected rows on mssql [#6930](https://github.com/sequelize/sequelize/pull/6930) - [FIXED] Soft-delete not returning number of affected rows on mssql [#6930](https://github.com/sequelize/sequelize/pull/6930)
- [FIXED] No `value` in built-in/custom validation errors [#3899](https://github.com/sequelize/sequelize/pull/3899)
## BC breaks: ## BC breaks:
- `DATEONLY` now returns string in `YYYY-MM-DD` format rather than `Date` type - `DATEONLY` now returns string in `YYYY-MM-DD` format rather than `Date` type
......
...@@ -228,7 +228,7 @@ class ValidationErrorItem { ...@@ -228,7 +228,7 @@ class ValidationErrorItem {
this.message = message || ''; this.message = message || '';
this.type = type || null; this.type = type || null;
this.path = path || null; this.path = path || null;
this.value = value || null; this.value = value !== undefined ? value : null;
} }
} }
exports.ValidationErrorItem = ValidationErrorItem; exports.ValidationErrorItem = ValidationErrorItem;
......
...@@ -198,7 +198,9 @@ class InstanceValidator { ...@@ -198,7 +198,9 @@ class InstanceValidator {
validators.push(validatorPromise.reflect()); validators.push(validatorPromise.reflect());
}); });
return Promise.all(validators).then(this._handleReflectedResult.bind(this, field)); return Promise
.all(validators)
.then(results => this._handleReflectedResult(field, value, results));
} }
/** /**
...@@ -235,9 +237,12 @@ class InstanceValidator { ...@@ -235,9 +237,12 @@ class InstanceValidator {
} else { } else {
validatorFunction = Promise.promisify(validator.bind(this.modelInstance)); validatorFunction = Promise.promisify(validator.bind(this.modelInstance));
} }
return validatorFunction().catch(this._pushError.bind(this, false, errorKey)); return validatorFunction()
.catch(e => this._pushError(false, errorKey, e, optValue));
} else { } else {
return Promise.try(validator.bind(this.modelInstance, invokeArgs)).catch(this._pushError.bind(this, false, errorKey)); return Promise
.try(() => validator.call(this.modelInstance, invokeArgs))
.catch(e => this._pushError(false, errorKey, e, optValue));
} }
} }
...@@ -328,14 +333,15 @@ class InstanceValidator { ...@@ -328,14 +333,15 @@ class InstanceValidator {
* If errors are found it populates this.error. * If errors are found it populates this.error.
* *
* @param {string} field The attribute name. * @param {string} field The attribute name.
* @param {string|number} value The data value.
* @param {Array.<Promise.PromiseInspection>} Promise inspection objects. * @param {Array.<Promise.PromiseInspection>} Promise inspection objects.
* @private * @private
*/ */
_handleReflectedResult(field, promiseInspections) { _handleReflectedResult(field, value, promiseInspections) {
for (const promiseInspection of promiseInspections) { for (const promiseInspection of promiseInspections) {
if (promiseInspection.isRejected()) { if (promiseInspection.isRejected()) {
const rejection = promiseInspection.error(); const rejection = promiseInspection.error();
this._pushError(true, field, rejection); this._pushError(true, field, rejection, value);
} }
} }
} }
...@@ -346,11 +352,12 @@ class InstanceValidator { ...@@ -346,11 +352,12 @@ class InstanceValidator {
* @param {boolean} isBuiltin Determines if error is from builtin validator. * @param {boolean} isBuiltin Determines if error is from builtin validator.
* @param {string} errorKey The error key to assign on this.errors object. * @param {string} errorKey The error key to assign on this.errors object.
* @param {Error|string} rawError The original error. * @param {Error|string} rawError The original error.
* @param {string|number} value The data that triggered the error.
* @private * @private
*/ */
_pushError(isBuiltin, errorKey, rawError) { _pushError(isBuiltin, errorKey, rawError, value) {
const message = rawError.message || rawError || 'Validation error'; const message = rawError.message || rawError || 'Validation error';
const error = new sequelizeError.ValidationErrorItem(message, 'Validation error', errorKey, rawError); const error = new sequelizeError.ValidationErrorItem(message, 'Validation error', errorKey, value);
error[InstanceValidator.RAW_KEY_NAME] = rawError; error[InstanceValidator.RAW_KEY_NAME] = rawError;
this.errors.push(error); this.errors.push(error);
......
...@@ -201,6 +201,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() { ...@@ -201,6 +201,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
return expect(failingUser.validate()).to.be.rejected.then(function(_errors) { return expect(failingUser.validate()).to.be.rejected.then(function(_errors) {
expect(_errors.get('name')[0].message).to.equal(message); expect(_errors.get('name')[0].message).to.equal(message);
expect(_errors.get('name')[0].value).to.equal(failingValue);
}); });
}); });
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!