From a79f92334f686eb40b06f117bed0b51ec0fad9f0 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sat, 27 Jun 2020 23:45:05 +0200 Subject: [PATCH] Use subErrors API, improve error output in case of nested errors --- index.js | 14 +++++++------- package.json | 2 +- src/are-arrays-equal.js | 15 +++++++++++++++ src/are-errors-from-same-origin.js | 16 ++++++++++++++++ yarn.lock | 27 +++++++++++++++++++++++---- 5 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 src/are-arrays-equal.js create mode 100644 src/are-errors-from-same-origin.js diff --git a/index.js b/index.js index ced8952..8d43a52 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,8 @@ const ValidationError = require("@validatem/error"); const combinator = require("@validatem/combinator"); const validationResult = require("@validatem/validation-result"); +const areErrorsFromSameOrigin = require("./src/are-errors-from-same-origin"); + module.exports = function (alternatives) { if (!Array.isArray(alternatives)) { throw new Error(`Must specify an array of alternatives`); @@ -46,15 +48,13 @@ module.exports = function (alternatives) { return (error.path.length === 0); }); - if (nestedErrors.length > 0) { - // At least one of the alternatives *did* match, but it failed somewhere further down the tree. Chances are that the user intended to match that branch, so we pretend that the other alternatives don't exist, and pass through the original error(s). + let sameOrigin = areErrorsFromSameOrigin(nestedErrors); + + if (nestedErrors.length > 0 && sameOrigin) { + // One of the alternatives *did* match, but it failed somewhere further down the tree, and we don't have any errors originating from *other* nested rules. Chances are that the user intended to match the failing branch, so we pretend that the other alternatives don't exist, and pass through the original error(s). return validationResult({ errors: nestedErrors }); } else { - let alternativesList = sameLevelErrors - .map((error) => `"${error.message}"`) - .join(", "); - - throw new ValidationError(`Must satisfy at least one of: ${alternativesList}`, { errors: sameLevelErrors }); + throw new ValidationError(`Must satisfy at least one of:`, { subErrors: allErrors }); } }); } diff --git a/package.json b/package.json index 7c71d11..a233405 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "author": "Sven Slootweg ", "license": "WTFPL OR CC0-1.0", "devDependencies": { - "@validatem/core": "^0.3.1", + "@validatem/core": "^0.3.4", "@validatem/is-number": "^0.1.2", "@validatem/is-string": "^0.1.1" }, diff --git a/src/are-arrays-equal.js b/src/are-arrays-equal.js new file mode 100644 index 0000000..7da2f5f --- /dev/null +++ b/src/are-arrays-equal.js @@ -0,0 +1,15 @@ +"use strict"; + +module.exports = function areArraysEqual(a, b) { + if (a.length !== b.length) { + return false; + } else { + for (let [ i, item ] of a.entries()) { + if (b[i] !== item) { + return false; + } + } + + return true; + } +}; diff --git a/src/are-errors-from-same-origin.js b/src/are-errors-from-same-origin.js new file mode 100644 index 0000000..7ea57b0 --- /dev/null +++ b/src/are-errors-from-same-origin.js @@ -0,0 +1,16 @@ +"use strict"; + +const areArraysEqual = require("./are-arrays-equal"); + +module.exports = function areErrorsFromSameOrigin(errors) { + let seenPath = null; + + return errors.every((error) => { + if (seenPath == null) { + seenPath = error.path; + return true; + } else { + return areArraysEqual(seenPath, error.path); + } + }); +}; diff --git a/yarn.lock b/yarn.lock index 28a7bee..8707d1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,10 +26,10 @@ resolved "https://registry.yarnpkg.com/@validatem/combinator/-/combinator-0.1.1.tgz#202f31243f8d57cf87f1b449405b134e2fa40c5a" integrity sha512-crzAYCmKUcb1DC5sSpdof4gWHX81VRmm+REWflhFuRlKH6JHRV5RcBCxEjlDfRrxW2yF6s9i0rQAOyVVE+GGAg== -"@validatem/core@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@validatem/core/-/core-0.3.1.tgz#33ea24ba4d4c516b5836703aea7e7da0afb6c227" - integrity sha512-k9OgvVqxX6rKmnkEQGi14pBqsilXu8pIVelaQsI/3tI5xVDDE5podpuPAJVrIsepy2berCtN9KSD/NCDhX1wLg== +"@validatem/core@^0.3.4": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@validatem/core/-/core-0.3.4.tgz#08dbad5927369db200ed301d00944533bdd71fe1" + integrity sha512-PtRQaTpfqnNrjJ1MDnHjAMcC1YSr0plt7XKKwP4oiNefephrZReykLd6dnRkV36UPNpYGiQq5QS9jnHJ/SQAcQ== dependencies: "@validatem/annotate-errors" "^0.1.2" "@validatem/any-property" "^0.1.0" @@ -45,7 +45,9 @@ create-error "^0.3.1" default-value "^1.0.0" flatten "^1.0.3" + indent-string "^4.0.0" is-arguments "^1.0.4" + supports-color "^7.1.0" "@validatem/error@^1.0.0": version "1.0.0" @@ -176,6 +178,16 @@ flatten@^1.0.3: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + is-arguments@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" @@ -200,3 +212,10 @@ split-filter@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/split-filter/-/split-filter-1.1.3.tgz#c68cc598783d88f60d16e7b452dacfe95ba60539" integrity sha512-2xXwhWeJUFrYE8CL+qoy9mCohu5/E+uglvpqL1FVXz1XbvTwivafVC6oTDeg/9ksOAxg6DvyCF44Dvf5crFU0w== + +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0"