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)
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