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