diff --git a/lib/linter/linter.js b/lib/linter/linter.js index bd1bbb7ca82..95a83366a37 100644 --- a/lib/linter/linter.js +++ b/lib/linter/linter.js @@ -1119,6 +1119,10 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO }; } + if (typeof ruleListeners === "undefined" || ruleListeners === null) { + throw new Error(`The create() function for rule '${ruleId}' did not return an object.`); + } + // add all the selectors from the rule as listeners Object.keys(ruleListeners).forEach(selector => { const ruleListener = timing.enabled diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index 05cb6d0f1d9..8239abd2086 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -7000,6 +7000,22 @@ var a = "test2"; assert(ok); }); + + it("should throw when rule's create() function does not return an object", () => { + const config = { rules: { checker: "error" } }; + + linter.defineRule("checker", () => null); // returns null + + assert.throws(() => { + linter.verify("abc", config, filename); + }, "The create() function for rule 'checker' did not return an object."); + + linter.defineRule("checker", () => {}); // returns undefined + + assert.throws(() => { + linter.verify("abc", config, filename); + }, "The create() function for rule 'checker' did not return an object."); + }); }); describe("Custom parser", () => {