class RuboCop::Cop::Naming::RescuedExceptionsVariableName
Makes sure that rescued exceptions variables are named as expected.
The `PreferredName` config option takes a `String`. It represents the required name of the variable. Its default is `e`.
NOTE: This cop does not consider nested rescues because it cannot guarantee that the variable from the outer rescue is not used within the inner rescue (in which case, changing the inner variable would shadow the outer variable).
@example PreferredName: e (default)
# bad begin # do something rescue MyException => exception # do something end # good begin # do something rescue MyException => e # do something end # good begin # do something rescue MyException => _e # do something end
@example PreferredName: exception
# bad begin # do something rescue MyException => e # do something end # good begin # do something rescue MyException => exception # do something end # good begin # do something rescue MyException => _exception # do something end
Constants
- MSG
Public Instance Methods
on_resbody(node)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 66 def on_resbody(node) offending_name = variable_name(node) return unless offending_name # Handle nested rescues by only requiring the outer one to use the # configured variable name, so that nested rescues don't use the same # variable. return if node.each_ancestor(:resbody).any? preferred_name = preferred_name(offending_name) return if preferred_name.to_sym == offending_name # check variable shadowing for exception variable return if shadowed_variable_name?(node) range = offense_range(node) message = message(node) add_offense(range, message: message) do |corrector| corrector.replace(range, preferred_name) correct_node(corrector, node.body, offending_name, preferred_name) end end
Private Instance Methods
correct_node(corrector, node, offending_name, preferred_name)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 108 def correct_node(corrector, node, offending_name, preferred_name) return unless node node.each_node(:lvar, :lvasgn, :masgn) do |child_node| next unless variable_name_matches?(child_node, offending_name) corrector.replace(child_node, preferred_name) if child_node.lvar_type? if child_node.masgn_type? || child_node.lvasgn_type? correct_reassignment(corrector, child_node, offending_name, preferred_name) break end end end
correct_reassignment(corrector, node, offending_name, preferred_name)
click to toggle source
If the exception variable is reassigned, that assignment needs to be corrected. Further `lvar` nodes will not be corrected though since they now refer to a different variable.
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 126 def correct_reassignment(corrector, node, offending_name, preferred_name) if node.lvasgn_type? correct_node(corrector, node.child_nodes.first, offending_name, preferred_name) elsif node.masgn_type? # With multiple assign, the assignments are in an array as the last child correct_node(corrector, node.children.last, offending_name, preferred_name) end end
message(node)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 151 def message(node) offending_name = variable_name(node) preferred_name = preferred_name(offending_name) format(MSG, preferred: preferred_name, bad: offending_name) end
offense_range(resbody)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 93 def offense_range(resbody) variable = resbody.exception_variable variable.loc.expression end
preferred_name(variable_name)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 135 def preferred_name(variable_name) preferred_name = cop_config.fetch('PreferredName', 'e') if variable_name.to_s.start_with?('_') "_#{preferred_name}" else preferred_name end end
shadowed_variable_name?(node)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 157 def shadowed_variable_name?(node) node.each_descendant(:lvar).any? { |n| n.children.first.to_s == preferred_name(n) } end
variable_name(node)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 144 def variable_name(node) asgn_node = node.exception_variable return unless asgn_node asgn_node.children.last end
variable_name_matches?(node, name)
click to toggle source
# File lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb, line 98 def variable_name_matches?(node, name) if node.masgn_type? node.each_descendant(:lvasgn).any? do |lvasgn_node| variable_name_matches?(lvasgn_node, name) end else node.children.first == name end end