Class: RuboCop::Cop::Axn::UncheckedResult

Inherits:
Base
  • Object
show all
Extended by:
RuboCop::Cop::AutoCorrector
Defined in:
lib/rubocop/cop/axn/unchecked_result.rb

Overview

This cop enforces that when calling Axns from within other Axns, you must either use call! (with the bang) or check result.ok?.

When the ActionsNamespace configuration is set (e.g., to "Actions"), the cop will only check calls on classes under that namespace, reducing false positives from other service objects.

rubocop:disable Metrics/ClassLength

Examples:

# bad
class OuterAction
  include Axn
  def call
    InnerAction.call(param: "value")  # Missing result check
  end
end

# good
class OuterAction
  include Axn
  def call
    result = InnerAction.call(param: "value")
    return result unless result.ok?
    # Process successful result...
  end
end

# also good
class OuterAction
  include Axn
  def call
    InnerAction.call!(param: "value")  # Using call! ensures exceptions bubble up
  end
end

With ActionsNamespace configured as string

# .rubocop.yml
Axn/UncheckedResult:
  ActionsNamespace: "Actions"

# This will only check Actions::* classes, not other service objects
class OuterAction
  include Axn
  def call
    SomeService.call(param: "value")  # Won't trigger cop
    Actions::InnerAction.call(param: "value")  # Will trigger cop
  end
end

With ActionsNamespace configured as array

# .rubocop.yml
Axn/UncheckedResult:
  ActionsNamespace: ["Actions", "Services"]

# This will check both Actions::* and Services::* classes
class OuterAction
  include Axn
  def call
    SomeService.call(param: "value")  # Won't trigger cop
    Actions::InnerAction.call(param: "value")  # Will trigger cop
    Services::SomeService.call(param: "value")  # Will trigger cop
  end
end

Constant Summary collapse

MSG =
"Use `call!` or check `result.ok?` when calling Axns from within Axns"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.configuration_schemaObject

Define the configuration schema



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rubocop/cop/axn/unchecked_result.rb', line 76

def self.configuration_schema
  @configuration_schema ||= RuboCop::ConfigSchema::Schema.new(
    {
      "ActionsNamespace" => {
        "type" => %w[string array],
        "description" => 'Only check calls on classes under this namespace (e.g., "Actions") or array of namespaces (e.g., ["Actions", "Services"])',
      },
      "CheckNested" => {
        "type" => "boolean",
        "description" => "Check nested Axn calls",
        "default" => true,
      },
      "CheckNonNested" => {
        "type" => "boolean",
        "description" => "Check non-nested Axn calls",
        "default" => true,
      },
    },
  )
end

Instance Method Details

#check_nested?Boolean

Configuration options

Returns:

  • (Boolean)


98
99
100
# File 'lib/rubocop/cop/axn/unchecked_result.rb', line 98

def check_nested?
  cop_config["CheckNested"] != false
end

#check_non_nested?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/rubocop/cop/axn/unchecked_result.rb', line 102

def check_non_nested?
  cop_config["CheckNonNested"] != false
end

#on_send(node) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/rubocop/cop/axn/unchecked_result.rb', line 159

def on_send(node)
  return unless axn_call?(node)
  return unless axn_action_call?(node)
  return if bang_call?(node)
  return unless inside_axn_call_method?(node)

  # Check if we should process this call based on configuration
  is_inside_action = inside_action_context?(node)
  return unless (is_inside_action && check_nested?) || (!is_inside_action && check_non_nested?)

  return if result_properly_handled?(node)

  add_offense(node, message: MSG)
end