class RuboCop::Cop::Style::RaiseArgs

This cop checks the args passed to `fail` and `raise`. For exploded style (default), it recommends passing the exception class and message to `raise`, rather than construct an instance of the error. It will still allow passing just a message, or the construction of an error with more than one argument.

The exploded style works identically, but with the addition that it will also suggest constructing error objects when the exception is passed multiple arguments.

@example

# EnforcedStyle: exploded

# bad
raise StandardError.new("message")

# good
raise StandardError, "message"
fail "message"
raise RuntimeError.new(arg1, arg2, arg3)

@example

# EnforcedStyle: compact

# bad
raise StandardError, "message"
raise RuntimeError, arg1, arg2, arg3

# good
raise StandardError.new("message")
raise RuntimeError.new(arg1, arg2, arg3)
fail "message"

Constants

COMPACT_MSG
EXPLODED_MSG

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 48
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

Private Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 61
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
check_compact(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 88
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
check_exploded(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 100
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
correction_compact_to_exploded(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 74
def correction_compact_to_exploded(node)
  exception_node, _new, message_node = *node.first

  "#{exception_node.const_name}, #{message_node.source}"
end
correction_exploded_to_compact(node) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 80
def correction_exploded_to_compact(node)
  exception_node, *message_nodes = *node

  messages = message_nodes.map(&:source).join(', ')

  "#{exception_node.const_name}.new(#{messages})"
end
message(method) click to toggle source
# File lib/rubocop/cop/style/raise_args.rb, line 121
def message(method)
  if style == :compact
    format(COMPACT_MSG, method)
  else
    format(EXPLODED_MSG, method)
  end
end