123456789_123456789_123456789_123456789_123456789_

Exception: RuboCop::Cop::Style::SignalException

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::RuboCop::Cop::AutoCorrector, ::RuboCop::Cop::Base, ::RuboCop::ExcludeLimit, NodePattern::Macros, RuboCop::AST::Sexp
Instance Chain:
Inherits: RuboCop::Cop::Base
Defined in: lib/rubocop/cop/style/signal_exception.rb

Overview

Checks for uses of fail and raise.

Examples:

EnforcedStyle: only_raise (default)

# The `only_raise` style enforces the sole use of `raise`.
# bad
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  # handle it
end

Kernel.fail

# good
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  raise
rescue Exception
  # handle it
end

Kernel.raise

EnforcedStyle: only_fail

# The `only_fail` style enforces the sole use of `fail`.
# bad
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  raise
rescue Exception
  # handle it
end

Kernel.raise

# good
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  # handle it
end

Kernel.fail

EnforcedStyle: semantic

# The `semantic` style enforces the use of `fail` to signal an
# exception, then will use `raise` to trigger an offense after
# it has been rescued.
# bad
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  # Error thrown
rescue Exception
  fail
end

Kernel.fail
Kernel.raise

# good
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  raise 'Preferably with descriptive message'
end

explicit_receiver.fail
explicit_receiver.raise

Constant Summary

::RuboCop::Cop::Base - Inherited

EMPTY_OFFENSES, RESTRICT_ON_SEND

::RuboCop::Cop::ConfigurableEnforcedStyle - Included

SYMBOL_TO_STRING_CACHE

Class Attribute Summary

::RuboCop::Cop::AutoCorrector - Extended

::RuboCop::Cop::Base - Inherited

.gem_requirements, .lint?,
.support_autocorrect?

Returns if class supports autocorrect.

.support_multiple_source?

Override if your cop should be called repeatedly for multiple investigations Between calls to on_new_investigation and on_investigation_end, the result of processed_source will remain constant.

.builtin?

Class Method Summary

::RuboCop::Cop::Base - Inherited

.autocorrect_incompatible_with

List of cops that should not try to autocorrect at the same time as this cop.

.badge

Naming.

.callbacks_needed, .cop_name, .department,
.documentation_url

Cops (other than builtin) are encouraged to implement this.

.exclude_from_registry

Call for abstract Cop classes.

.inherited,
.joining_forces

Override and return the Force class(es) you need to join.

.match?

Returns true if the cop name or the cop namespace matches any of the given names.

.new,
.requires_gem

Register a version requirement for the given gem name.

.restrict_on_send

::RuboCop::ExcludeLimit - Extended

exclude_limit

Sets up a configuration option to have an exclude limit tracked.

transform

Instance Attribute Summary

Instance Method Summary

::RuboCop::Cop::ConfigurableEnforcedStyle - Included

::RuboCop::Cop::Base - Inherited

#add_global_offense

Adds an offense that has no particular location.

#add_offense

Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense.

#begin_investigation

Called before any investigation.

#callbacks_needed,
#cop_config

Configuration Helpers.

#cop_name, #excluded_file?,
#external_dependency_checksum

This method should be overridden when a cop’s behavior depends on state that lives outside of these locations:

#inspect,
#message

Gets called if no message is specified when calling add_offense or add_global_offense Cops are discouraged to override this; instead pass your message directly.

#name

Alias for Base#cop_name.

#offenses,
#on_investigation_end

Called after all on_…​

#on_new_investigation

Called before all on_…​

#on_other_file

Called instead of all on_…​

#parse

There should be very limited reasons for a Cop to do it’s own parsing.

#parser_engine,
#ready

Called between investigations.

#relevant_file?, #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction,
#callback_argument

Reserved for Cop::Cop.

#complete_investigation

Called to complete an investigation.

#correct, #current_corrector,
#current_offense_locations

Reserved for Commissioner:

#current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, #file_name_matches_any?, #find_message, #find_severity, #range_for_original, #range_from_node_or_range, #reset_investigation, #use_corrector

::RuboCop::Cop::AutocorrectLogic - Included

::RuboCop::Cop::IgnoredNode - Included

Constructor Details

This class inherits a constructor from RuboCop::Cop::Base

Instance Attribute Details

#custom_fail_defined?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 149

def custom_fail_defined?
  return @custom_fail_defined if defined?(@custom_fail_defined)

  ast = processed_source.ast
  @custom_fail_defined = ast && custom_fail_methods(ast).any?
end

Instance Method Details

#allow(method_name, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 206

def allow(method_name, node)
  each_command_or_kernel_call(method_name, node) { |send_node| ignore_node(send_node) }
end

#autocorrect(corrector, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 188

def autocorrect(corrector, node)
  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

#check_scope(method_name, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 167

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.loc.selector, message: message(method_name)) do |corrector|
      autocorrect(corrector, send_node)
    end
    ignore_node(send_node)
  end
end

#check_send(method_name, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 180

def check_send(method_name, node)
  return unless node && command_or_kernel_call?(method_name, node)

  add_offense(node.loc.selector, message: message(method_name)) do |corrector|
    autocorrect(corrector, node)
  end
end

#command_or_kernel_call?(name, node) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 200

def command_or_kernel_call?(name, node)
  return false unless node.method?(name)

  node.command?(name) || kernel_call?(node, name)
end

#custom_fail_methods(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 120

def_node_search :custom_fail_methods, '{(def :fail ...) (defs _ :fail ...)}'

#each_command_or_kernel_call(method_name, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 210

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

#kernel_call?(node, name)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 117

def_node_matcher :kernel_call?, '(send (const {nil? cbase} :Kernel) %1 ...)'

#message(method_name) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 156

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

#on_rescue(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 122

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

#on_send(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/style/signal_exception.rb', line 134

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