diff --git a/packages/metal-state/src/State.js b/packages/metal-state/src/State.js index 441b4e2e..45b17e87 100644 --- a/packages/metal-state/src/State.js +++ b/packages/metal-state/src/State.js @@ -55,6 +55,14 @@ class State extends EventEmitter { */ this.scheduledBatchData_ = null; + /** + * Throws exception when validator returns an `Error` instance. + * @type {boolean} + * @default false + * @protected + */ + this.throwValidationError_ = false; + /** * Object that contains information about all this instance's state keys. * @type {!Object} @@ -96,6 +104,21 @@ class State extends EventEmitter { } } + /** + * Logs an error if the `validatorReturn` is instance of `Error`. + * @param {*} validatorReturn + * @protected + */ + assertValidatorReturnInstanceOfError_(validatorReturn) { + if (validatorReturn instanceof Error) { + if (this.getThrowValidationError()) { + throw validatorReturn; + } else { + console.error(`Warning: ${validatorReturn}`); + } + } + } + /** * Checks that the given name is a valid state key name. If it's not, an error * will be thrown. @@ -178,10 +201,7 @@ class State extends EventEmitter { config.validator, [value, name, this.context_] ); - - if (validatorReturn instanceof Error) { - console.error(`Warning: ${validatorReturn}`); - } + this.assertValidatorReturnInstanceOfError_(validatorReturn); return validatorReturn; } return true; @@ -368,6 +388,15 @@ class State extends EventEmitter { } } + /** + * Gets the configuration value for whether or not should throw error when + * vaildator functions returns an `Error` instance. + * @return {boolean} + */ + getThrowValidationError() { + return this.throwValidationError_; + } + /** * Merges the STATE static variable for the given constructor function. * @param {!Function} ctor Constructor function. @@ -607,6 +636,15 @@ class State extends EventEmitter { (isObject(prevVal) || prevVal !== this.get(name)); } + /** + * Sets the configuration value for whether or not should throw error when + * vaildator functions returns an `Error` instance. + * @param {boolean} throwValidationError + */ + setThrowValidationError(throwValidationError) { + this.throwValidationError_ = throwValidationError; + } + /** * Validates the initial value for the state property with the given name. * @param {string} name diff --git a/packages/metal-state/test/State.js b/packages/metal-state/test/State.js index cfdb1b25..be40f659 100644 --- a/packages/metal-state/test/State.js +++ b/packages/metal-state/test/State.js @@ -390,6 +390,39 @@ describe('State', function() { console.error = originalConsoleFn; }); + it('should throw error if validator returns an Error and throwValidationError is enabled', function() { + var state = new State(); + state.setThrowValidationError(true); + state.configState( + { + key1: { + validator: function() { + return new Error(); + } + } + } + ); + + assert.throws(() => state.key1 = 1); + }); + + it('should not throw error if validator returns an Error and throwValidationError is disabled', function() { + var state = new State(); + state.setThrowValidationError(false); + state.configState( + { + key1: { + validator: function() { + return new Error(); + } + } + } + ); + + assert.doesNotThrow(() => state.key1 = 1); + assert.strictEqual(1, state.key1); + }); + it('should change state new value through setter', function() { var state = new State(); state.configState({