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