Class: Axn::Result

Inherits:
ContextFacade show all
Defined in:
lib/axn/result.rb

Overview

Outbound / External ContextFacade

Constant Summary collapse

OUTCOMES =

Outcome constants for action execution results

[
  OUTCOME_SUCCESS = "success",
  OUTCOME_FAILURE = "failure",
  OUTCOME_EXCEPTION = "exception",
].freeze

Instance Attribute Summary

Attributes inherited from ContextFacade

#declared_fields

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ContextFacade

#fail!, #inspect

Constructor Details

#initializeResult

Returns a new instance of Result.



9
10
11
12
# File 'lib/axn/result.rb', line 9

def initialize(...)
  super
  _define_boolean_predicate_readers
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name) ⇒ Object (private)

rubocop:disable Style/MissingRespondToMissing (because we’re not actually responding to anything additional)



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/axn/result.rb', line 140

def method_missing(method_name, ...) # rubocop:disable Style/MissingRespondToMissing (because we're not actually responding to anything additional)
  if @context.__combined_data.key?(method_name.to_sym)
    msg = <<~MSG
      Method ##{method_name} is not available on Action::Result!

      #{action_name} may be missing a line like:
        exposes :#{method_name}
    MSG

    raise Axn::ContractViolation::MethodNotAllowed, msg
  end

  super
end

Class Method Details

.error(msg = nil, **exposures, &block) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/axn/result.rb', line 26

def error(msg = nil, **exposures, &block)
  exposes = exposures.keys.to_h { |key| [key, { optional: true }] }

  Axn::Factory.build(exposes:, error: msg, log_calls: false, log_errors: false) do
    exposures.each do |key, value|
      expose(key, value)
    end
    if block_given?
      begin
        block.call
      rescue StandardError => e
        # Set the exception directly without triggering on_exception handlers
        @__context.__record_exception(e)
      end
    else
      fail! msg
    end
  end.call
end

.ok(msg = nil, **exposures) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/axn/result.rb', line 16

def ok(msg = nil, **exposures)
  exposes = exposures.keys.to_h { |key| [key, { optional: true }] }

  Axn::Factory.build(exposes:, success: msg, log_calls: false, log_errors: false) do
    exposures.each do |key, value|
      expose(key, value)
    end
  end.call
end

Instance Method Details

#__action__Object

Internal accessor for the action instance TODO: exposed for errors :from support, but should be private if possible



85
# File 'lib/axn/result.rb', line 85

def __action__ = @action

#deconstruct_keys(keys) ⇒ Object

Enable pattern matching support for Ruby 3+



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/axn/result.rb', line 88

def deconstruct_keys(keys)
  attrs = {
    ok: ok?,
    success:,
    error:,
    message:,
    outcome: outcome.to_sym,
    finalized: finalized?,
  }

  # Add all exposed data
  attrs.merge!(@context.exposed_data)

  # Return filtered attributes if keys specified
  keys ? attrs.slice(*keys) : attrs
end

#errorObject



50
51
52
53
54
# File 'lib/axn/result.rb', line 50

def error
  return if ok?

  _user_provided_error_message || _msg_resolver(:error, exception:).resolve_message
end

#messageObject



62
# File 'lib/axn/result.rb', line 62

def message = exception ? error : success

#outcomeObject



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/axn/result.rb', line 71

def outcome
  label = if exception.is_a?(Axn::Failure)
            OUTCOME_FAILURE
          elsif exception
            OUTCOME_EXCEPTION
          else
            OUTCOME_SUCCESS
          end

  ActiveSupport::StringInquirer.new(label)
end

#successObject



56
57
58
59
60
# File 'lib/axn/result.rb', line 56

def success
  return unless ok?

  _user_provided_success_message || _msg_resolver(:success, exception: nil).resolve_message
end