class RuboCop::Cop::Style::RaiseArgs
fail “message”
raise RuntimeError.new(arg1, arg2, arg3)
raise StandardError.new(“message”)
# good
raise RuntimeError, arg1, arg2, arg3
raise StandardError, “message”
# bad
# EnforcedStyle: compact
@example
raise RuntimeError.new(arg1, arg2, arg3)
fail “message”
raise StandardError, “message”
# good
raise StandardError.new(“message”)
# bad
# EnforcedStyle: exploded
@example
passed multiple arguments.
will also suggest constructing error objects when the exception is
The exploded style works identically, but with the addition that it
with more than one argument.
still allow passing just a message, or the construction of an error
to ‘raise`, rather than construct an instance of the error. It will
style (default), it recommends passing the exception class and message
This cop checks the args passed to `fail` and `raise`. For exploded
def autocorrect(node)
def autocorrect(node) _scope, method, *args = *node new_exception = if style == :compact correction_exploded_to_compact(args) else correction_compact_to_exploded(args) end replacement = "#{method} #{new_exception}" ->(corrector) { corrector.replace(node.source_range, replacement) } end
def check_compact(node)
def check_compact(node) _receiver, selector, *args = *node if args.size > 1 add_offense(node, :expression, message(selector)) do opposite_style_detected end else correct_style_detected end end
def check_exploded(node)
def check_exploded(node) _receiver, selector, *args = *node if args.size == 1 arg, = *args if arg.type == :send && arg.loc.selector.is?('new') _receiver, _selector, *constructor_args = *arg # Allow code like `raise Ex.new(arg1, arg2)`. if constructor_args.size <= 1 add_offense(node, :expression, message(selector)) do opposite_style_detected end end end else correct_style_detected end end
def correction_compact_to_exploded(node)
def correction_compact_to_exploded(node) exception_node, _new, message_node = *node.first "#{exception_node.const_name}, #{message_node.source}" end
def correction_exploded_to_compact(node)
def correction_exploded_to_compact(node) exception_node, *message_nodes = *node messages = message_nodes.map(&:source).join(', ') "#{exception_node.const_name}.new(#{messages})" end
def message(method)
def message(method) if style == :compact format(COMPACT_MSG, method) else format(EXPLODED_MSG, method) end end
def on_send(node)
def on_send(node) return unless node.command?(:raise) || node.command?(:fail) case style when :compact check_compact(node) when :exploded check_exploded(node) end end