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