class RuboCop::Cop::Lint::UselessRescue


end
# noop
rescue
raise
rescue ArgumentError
do_something
def foo
# good (not the latest rescue)
end
raise
rescue
# noop
rescue ArgumentError
do_something
def foo
# bad (latest rescue)
end
raise
do_cleanup
rescue
do_something
def foo
# good
end
raise # or ‘raise e’, or ‘raise $!’, or ‘raise $ERROR_INFO’
rescue => e
do_something
def foo
# bad
end
raise
rescue
do_something
def foo
# bad
@example
Checks for useless “rescue“s, which only reraise rescued exceptions.

def exception_objects(resbody_node)

def exception_objects(resbody_node)
  [resbody_node.exception_variable&.source, '$!', '$ERROR_INFO']
end

def on_rescue(node)

def on_rescue(node)
  resbody_node = node.resbody_branches.last
  add_offense(resbody_node) if only_reraising?(resbody_node)
end

def only_reraising?(resbody_node)

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
def only_reraising?(resbody_node)
  return false if use_exception_variable_in_ensure?(resbody_node)
  body = resbody_node.body
  return false if body.nil? || !body.send_type? || !body.method?(:raise) || body.receiver
  return true unless body.arguments?
  return false if body.arguments.size > 1
  exception_name = body.first_argument.source
  exception_objects(resbody_node).include?(exception_name)
end

def use_exception_variable_in_ensure?(resbody_node)

def use_exception_variable_in_ensure?(resbody_node)
  return false unless (exception_variable = resbody_node.exception_variable)
  return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
  return false unless (ensure_body = ensure_node.branch)
  ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
end