class Gitlab::Styles::Rubocop::Cop::CustomErrorClass

This cop makes sure that custom error classes, when empty, are declared with Class.new.

@example

# bad
class FooError < StandardError
end

# okish
class FooError < StandardError; end

# good
FooError = Class.new(StandardError)

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/gitlab/styles/rubocop/cop/custom_error_class.rb, line 36
def autocorrect(node)
  klass = node.identifier
  parent = node.parent_class

  replacement = "#{class_name_from_node(klass)} = Class.new(#{class_name_from_node(parent)})"

  lambda do |corrector|
    corrector.replace(node.source_range, replacement)
  end
end
on_class(node) click to toggle source
# File lib/gitlab/styles/rubocop/cop/custom_error_class.rb, line 23
def on_class(node)
  parent = node.parent_class
  body = node.body

  return if body

  parent_klass = class_name_from_node(parent)

  return unless parent_klass&.to_s&.end_with?('Error')

  add_offense(node)
end

Private Instance Methods

class_name_from_node(node, suffix = nil) click to toggle source

The nested constant `Foo::Bar::Baz` looks like:

s(:const,
  s(:const,
    s(:const, nil, :Foo), :Bar), :Baz)

So recurse through that to get the name as written in the source.

# File lib/gitlab/styles/rubocop/cop/custom_error_class.rb, line 57
def class_name_from_node(node, suffix = nil)
  return unless node&.type == :const

  name = node.children[1].to_s
  name = "#{name}::#{suffix}" if suffix

  if node.children[0]
    class_name_from_node(node.children[0], name)
  else
    name
  end
end