class RuboCop::Cop::Style::SignalException
explicit_receiver.raise
explicit_receiver.fail
end
raise ‘Preferably with descriptive message’
rescue Exception
fail
def watch_out
end
# handle it
rescue Exception
fail
begin
# good
Kernel.raise
Kernel.fail
end
fail
rescue Exception
# Error thrown
def watch_out
end
# handle it
rescue Exception
raise
begin
# bad
# it has been rescued.
# exception, then will use ‘raise` to trigger an offense after
# The `semantic` style enforces the use of `fail` to signal an
@example EnforcedStyle: semantic
Kernel.fail
end
# handle it
rescue Exception
fail
def watch_out
end
# handle it
rescue Exception
fail
begin
# good
Kernel.raise
end
# handle it
rescue Exception
raise
def watch_out
end
# handle it
rescue Exception
raise
begin
# bad
# The `only_fail` style enforces the sole use of `fail`.
@example EnforcedStyle: only_fail
Kernel.raise
end
# handle it
rescue Exception
raise
def watch_out
end
# handle it
rescue Exception
raise
begin
# good
Kernel.fail
end
# handle it
rescue Exception
fail
def watch_out
end
# handle it
rescue Exception
fail
begin
# bad
# The `only_raise` style enforces the sole use of `raise`.
@example EnforcedStyle: only_raise (default)
This cop checks for uses of `fail` and `raise`.
def allow(method_name, node)
def allow(method_name, node) each_command_or_kernel_call(method_name, node) do |send_node| ignore_node(send_node) end end
def autocorrect(node)
def autocorrect(node) lambda do |corrector| name = case style when :semantic command_or_kernel_call?(:raise, node) ? 'fail' : 'raise' when :only_raise then 'raise' when :only_fail then 'fail' end corrector.replace(node.loc.selector, name) end end
def check_scope(method_name, node)
def check_scope(method_name, node) return unless node each_command_or_kernel_call(method_name, node) do |send_node| next if ignored_node?(send_node) add_offense(send_node, location: :selector, message: message(method_name)) ignore_node(send_node) end end
def check_send(method_name, node)
def check_send(method_name, node) return unless node && command_or_kernel_call?(method_name, node) add_offense(node, location: :selector, message: message(method_name)) end
def command_or_kernel_call?(name, node)
def command_or_kernel_call?(name, node) node.command?(name) || kernel_call?(node, name) end
def each_command_or_kernel_call(method_name, node)
def each_command_or_kernel_call(method_name, node) on_node(:send, node, :rescue) do |send_node| yield send_node if command_or_kernel_call?(method_name, send_node) end end
def investigate(processed_source)
def investigate(processed_source) ast = processed_source.ast @custom_fail_defined = ast && custom_fail_methods(ast).any? end
def message(method_name)
def message(method_name) case style when :semantic method_name == :fail ? RAISE_MSG : FAIL_MSG when :only_raise 'Always use `raise` to signal exceptions.' when :only_fail 'Always use `fail` to signal exceptions.' end end
def on_rescue(node)
def on_rescue(node) return unless style == :semantic begin_node, *rescue_nodes, _else_node = *node check_scope(:raise, begin_node) rescue_nodes.each do |rescue_node| check_scope(:fail, rescue_node) allow(:raise, rescue_node) end end
def on_send(node)
def on_send(node) case style when :semantic check_send(:raise, node) unless ignored_node?(node) when :only_raise return if @custom_fail_defined check_send(:fail, node) when :only_fail check_send(:raise, node) end end