• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview Ensure handling of errors when we know they exist.
3 * @author Jamund Ferguson
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13    meta: {
14        deprecated: true,
15
16        replacedBy: [],
17
18        type: "suggestion",
19
20        docs: {
21            description: "require error handling in callbacks",
22            category: "Node.js and CommonJS",
23            recommended: false,
24            url: "https://eslint.org/docs/rules/handle-callback-err"
25        },
26
27        schema: [
28            {
29                type: "string"
30            }
31        ],
32        messages: {
33            expected: "Expected error to be handled."
34        }
35    },
36
37    create(context) {
38
39        const errorArgument = context.options[0] || "err";
40
41        /**
42         * Checks if the given argument should be interpreted as a regexp pattern.
43         * @param {string} stringToCheck The string which should be checked.
44         * @returns {boolean} Whether or not the string should be interpreted as a pattern.
45         */
46        function isPattern(stringToCheck) {
47            const firstChar = stringToCheck[0];
48
49            return firstChar === "^";
50        }
51
52        /**
53         * Checks if the given name matches the configured error argument.
54         * @param {string} name The name which should be compared.
55         * @returns {boolean} Whether or not the given name matches the configured error variable name.
56         */
57        function matchesConfiguredErrorName(name) {
58            if (isPattern(errorArgument)) {
59                const regexp = new RegExp(errorArgument, "u");
60
61                return regexp.test(name);
62            }
63            return name === errorArgument;
64        }
65
66        /**
67         * Get the parameters of a given function scope.
68         * @param {Object} scope The function scope.
69         * @returns {Array} All parameters of the given scope.
70         */
71        function getParameters(scope) {
72            return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter");
73        }
74
75        /**
76         * Check to see if we're handling the error object properly.
77         * @param {ASTNode} node The AST node to check.
78         * @returns {void}
79         */
80        function checkForError(node) {
81            const scope = context.getScope(),
82                parameters = getParameters(scope),
83                firstParameter = parameters[0];
84
85            if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) {
86                if (firstParameter.references.length === 0) {
87                    context.report({ node, messageId: "expected" });
88                }
89            }
90        }
91
92        return {
93            FunctionDeclaration: checkForError,
94            FunctionExpression: checkForError,
95            ArrowFunctionExpression: checkForError
96        };
97
98    }
99};
100