From 78fc7bf9d4efe2a2d688a1dbed6498c2c86ab0bf Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Fri, 8 Jan 2016 22:54:50 -0800 Subject: [PATCH] Properly initialize and return Error objects Previously errors would be created like: var err = new Error({message: 'foo'}); If you try to print this via `console.log`, you get the message: Error: [object Object] The constructor for error takes a string as the first argument, so instead of passing a dictionary we just pass the string value. Furthermore, instead of passing back bare dictionaries when inputs fail validation, we pass back instances of Error objects, which have stack traces attached, and would pass checks like (err instanceof Error). --- lib/match/errorFactory.js | 15 +++++++-------- lib/match/matchRule.js | 9 ++++----- lib/match/matchType.js | 22 ++++++++++------------ test/util/testType.js | 6 ++++++ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/match/errorFactory.js b/lib/match/errorFactory.js index 026d97e..01fd23a 100644 --- a/lib/match/errorFactory.js +++ b/lib/match/errorFactory.js @@ -42,12 +42,11 @@ module.exports = function errorFactory(value, ruleName, keyName, customMessage) // Construct error object - return [{ - property: keyName, - data: value, - message: errMsg, - rule: ruleName, - actualType: typeof value, - expectedType: ruleName - }]; + var err = new Error(errMsg); + err.property = keyName; + err.data = value; + err.rule = ruleName; + err.actualType = typeof value; + err.expectedType = ruleName; + return [err]; }; diff --git a/lib/match/matchRule.js b/lib/match/matchRule.js index 33e6e5d..2c3e292 100644 --- a/lib/match/matchRule.js +++ b/lib/match/matchRule.js @@ -44,11 +44,10 @@ module.exports = function matchRule (data, ruleName, args) { // If outcome is false, an error occurred if (!outcome) { - return [{ - rule: ruleName, - data: data, - message: util.format('"%s" validation rule failed for input: %s', ruleName, util.inspect(data)) - }]; + var err = new Error(util.format('"%s" validation rule failed for input: %s', ruleName, util.inspect(data))); + err.data = data; + err.rule = ruleName; + return [err]; } else { return []; diff --git a/lib/match/matchType.js b/lib/match/matchType.js index 04c75a4..a20c018 100644 --- a/lib/match/matchType.js +++ b/lib/match/matchType.js @@ -44,7 +44,7 @@ function deepMatchType(data, ruleset, depth, keyName, customMessage) { depth = depth || 0; if (depth > MAX_DEPTH) { return [ - new Error({ message: 'Exceeded MAX_DEPTH when validating object. Maybe it\'s recursively referencing itself?'}) + new Error('Exceeded MAX_DEPTH when validating object. Maybe it\'s recursively referencing itself?') ]; } @@ -63,7 +63,7 @@ function deepMatchType(data, ruleset, depth, keyName, customMessage) { if (ruleset.length !== 0) { if (ruleset.length > 1) { return [ - new Error({ message: '[] (or schema) rules must contain exactly one item.'}) + new Error('[] (or schema) rules must contain exactly one item.') ]; } @@ -103,13 +103,12 @@ function deepMatchType(data, ruleset, depth, keyName, customMessage) { // Don't allow a `$message` without a `$validate` if (_customMessage) { if (!subValidation) { - return [{ - code: 'E_USAGE', - status: 500, - $message: _customMessage, - property: keyName, - message: 'Custom messages ($message) require a subvalidation - please specify a `$validate` option on `'+keyName+'`' - }]; + var err = new Error('Custom messages ($message) require a subvalidation - please specify a `$validate` option on `'+keyName+'`'); + err.status = 500; + err.code = 'E_USAGE'; + err.$message = _customMessage; + err.property = keyName; + return [err]; } else { // Use the specified message as the `customMessage` @@ -121,7 +120,7 @@ function deepMatchType(data, ruleset, depth, keyName, customMessage) { if (subValidation) { if (!subValidation.type) { return [ - new Error({message: 'Sub-validation rules (i.e. using $validate) other than `type` are not currently supported'}) + new Error('Sub-validation rules (i.e. using $validate) other than `type` are not currently supported') ]; } @@ -204,7 +203,7 @@ function matchType(datum, ruleName, keyName, customMessage) { // Determine outcome if (!rule) { return [ - new Error({message:'Unknown rule: ' + ruleName}) + new Error('Unknown rule: ' + ruleName) ]; } else outcome = rule.call(self, datum); @@ -222,4 +221,3 @@ function matchType(datum, ruleName, keyName, customMessage) { } } - diff --git a/test/util/testType.js b/test/util/testType.js index 932bd3a..02e2c1a 100644 --- a/test/util/testType.js +++ b/test/util/testType.js @@ -26,6 +26,12 @@ module.exports = function testType (rule, example, nonexample) { if (!_.isArray(nonexampleOutcome)) { return gotErrors('Invalid input (' + nonexample + ') allowed through as a ' + rule + '.'); } + for (var i = 0; i < nonexampleOutcome.length; i++) { + var err = nonexampleOutcome[i]; + if (!err instanceof Error) { + return gotErrors('Input ' + err + " should have been instanceof Error, wasn't"); + } + } function gotErrors (err) { console.error('*****************');