Repository: eslint/eslint
Pull request #9561 (2017-11-01 22:17:58)

Fix: Correct [object Object] output of error.data.
Stops error.data from being output as [object Object] when the data property
is an object, such as a rule’s options object.

<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[x] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->
**Tell us about your environment**

* **ESLint Version:**
4.10.0
* **Node Version:**
9.0.0
* **npm Version:**
5.5.1
**What parser (default, Babel-ESLint, etc.) are you using?**
default
**Please show your full configuration:**
```
"use strict";

const path = require("path");
const rulesDirPlugin = require("eslint-plugin-rulesdir");

rulesDirPlugin.RULES_DIR = path.join(__dirname, "tools/internal-rules");

module.exports = {
    root: true,
    plugins: [
        "eslint-plugin",
        "node",
        "rulesdir"
    ],
    extends: [
        "./packages/eslint-config-eslint/default.yml",
        "plugin:node/recommended",
        "plugin:eslint-plugin/recommended"
    ],
    rules: {
        "eslint-plugin/consistent-output": "error",
        "eslint-plugin/no-deprecated-context-methods": "error",
        "eslint-plugin/prefer-output-null": "error",
        "eslint-plugin/prefer-placeholders": "error",
        "eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"],
        "eslint-plugin/test-case-property-ordering": "error",
        "eslint-plugin/test-case-shorthand-strings": "error",
        "rulesdir/multiline-comment-style": "error"
    }
};
```
**What did you do? Please include the actual source code causing the issue.**
In a test file in `test/lib/rules`, in an invalidity test, set the value of `options` to an array of 1 option, which contained a property whose name was not specified in the schema of the rule. For example, set line 398 of `test/lib/rules/object-property-newline.js` to:
`options: [{ XallowMultiplePropertiesPerLineX: true }],`
**What did you expect to happen?**
I expected an intelligible error message explaining what was wrong.
**What actually happened? Please include the actual, raw output from ESLint.**
I received an error message that did not sufficiently explain what was wrong, namely:
`Value [object Object] should NOT have additional properties`.
<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**
1. I modified `config-validator` to check for the type of error.data. If error.data has a type other than string and is not an array, I changed it to its JSON stringification.
2. I modified the expected error messages of 2 config-validator tests to match the formats of error.data that arise from their JSON stringification.

**Is there anything you'd like reviewers to focus on?**
Would it be better to check for other types not yet in use, or to invert the check and check only for non-array objects, or to JSON stringify everything regardless of type?



mysticatea: Thank you for the contribution!

Looks great to me.
Personally, I think better if it JSON-stringify everything regardless of type.
jrpool: Thank you for your comment, @mysticatea. I’ll be happy to make that change, unless anybody else disagrees.
platinumazure: With the `error.data` no longer surrounded by quotation marks, I would also be okay with unconditional stringification. Thanks!

Patch:
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index 84990a758..a1bc8f6bf 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -60,7 +60,7 @@ The first line of the commit message (the summary) must have a specific format.
 The `Tag` is one of the following:
 
 * `Fix` - for a bug fix.
-* `Update` - for a backwards-compatible enhancement or a change to a rule that increases the number of reported problems.
+* `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems.
 * `New` - implemented a new feature.
 * `Breaking` - for a backwards-incompatible enhancement or feature.
 * `Docs` - changes to documentation only.
diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js
index 5aeb635c1..f2307dc63 100644
--- a/lib/config/config-validator.js
+++ b/lib/config/config-validator.js
@@ -89,7 +89,9 @@ function validateRuleSchema(id, localOptions, rulesContext) {
     if (validateRule) {
         validateRule(localOptions);
         if (validateRule.errors) {
-            throw new Error(validateRule.errors.map(error => `\tValue "${error.data}" ${error.message}.\n`).join(""));
+            throw new Error(validateRule.errors.map(
+                error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`
+            ).join(""));
         }
     }
 }
diff --git a/packages/eslint-config-eslint/README.md b/packages/eslint-config-eslint/README.md
index 36635964d..d1c3dd0cb 100644
--- a/packages/eslint-config-eslint/README.md
+++ b/packages/eslint-config-eslint/README.md
@@ -5,7 +5,7 @@
 
 [Website](https://eslint.org) | [Configuring](https://eslint.org/docs/user-guide/configuring) | [Rules](https://eslint.org/docs/rules/) | [Contributing](https://eslint.org/docs/developer-guide/contributing) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint)
 
-Contains the default ESLint configuration for ESLint projects.
+Contains the ESLint configuration used for projects maintained by the ESLint team.
 
 ## Installation
 


Test patch:
diff --git a/tests/lib/config/config-validator.js b/tests/lib/config/config-validator.js
index 71503ef6e..5f3d65278 100644
--- a/tests/lib/config/config-validator.js
+++ b/tests/lib/config/config-validator.js
@@ -352,7 +352,7 @@ describe("Validator", () => {
 
                 const fn = validator.validate.bind(null, { rules: { "mock-no-options-rule": [2, "extra"] } }, "tests", linter.rules, linter.environments);
 
-                assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-no-options-rule\" is invalid:\n\tValue \"extra\" should NOT have more than 0 items.\n");
+                assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-no-options-rule\" is invalid:\n\tValue [\"extra\"] should NOT have more than 0 items.\n");
             });
         });
 
@@ -458,7 +458,7 @@ describe("Validator", () => {
         it("should throw for too many configuration values", () => {
             const fn = validator.validateRuleOptions.bind(null, "mock-rule", [2, "first", "second"], "tests", linter.rules);
 
-            assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-rule\" is invalid:\n\tValue \"first,second\" should NOT have more than 1 items.\n");
+            assert.throws(fn, "tests:\n\tConfiguration for rule \"mock-rule\" is invalid:\n\tValue [\"first\",\"second\"] should NOT have more than 1 items.\n");
         });
 
     });