UNPKG

coffeelint-callback-handle-error

Version:

Coffeelint rule finds instances of error objects passed through a callback not being handled

94 lines (78 loc) 2.88 kB
getNodeType = (node) -> return node.constructor.name module.exports = class CallbackHandleError rule: name: 'callback_handle_error' level: 'error' message: 'Error in callback not handled' description: ''' Finds instances of error objects passed through a callback not being handled ''' # param name config patterns: ["^err(or)?", "[Ee]rr(or)?$"] lintAST: (node, @astApi) -> patterns = @astApi.config.patterns ? @rule.patterns @errorVariablePatterns = (new RegExp(pattern) for pattern in patterns) @lintNode node return lintNode: (node) -> node_type = getNodeType(node) switch node_type when 'Code' for param in node.params var_name = param.name?.value for pattern in @errorVariablePatterns if pattern.test(var_name) && !@handlesError(node, var_name) @throwError node, "Error object '#{var_name}' in callback not handled" break node.eachChild (child)=> @lintNode child return return handlesError: (code_node, var_name)-> found_usage = false code_node.traverseChildren true, (child)-> node_type = getNodeType child switch node_type when 'If' # check for if they use the error in an if child.condition.traverseChildren false, (inner_child)-> inner_type = getNodeType inner_child switch inner_type # HACK: Handles change of token naming in CoffeeScript 1.11.0 when 'Literal', 'IdentifierLiteral' if inner_child.value is var_name found_usage = true return false return when 'Call' # passing the error to another call is considered using it for arg in child.args arg.traverseChildren false, (inner_child)-> inner_type = getNodeType inner_child switch inner_type # HACK: Handles change of token naming in CoffeeScript 1.11.0 when 'Literal', 'IdentifierLiteral' if inner_child.value is var_name found_usage = true return false return return when 'Code' # stop going down the chain when the var gets overwritten with another param for param in child.params inner_child_type = getNodeType param if inner_child_type is 'Param' if param.name.value is var_name return false # if we already found a usage, break out of the traverse if found_usage return false return return found_usage throwError: (node, message) -> err = @astApi.createError lineNumber: node.locationData.first_line + 1 message: message @errors.push err return