Module: HatiCommand::Befehl::BefehlClassMethods

Defined in:
lib/hati_command/befehl.rb

Overview

Provides class methods for command configuration and execution. These methods are automatically added to any class that extends Befehl.

Constant Summary collapse

ERR =
HatiCommand::Errors

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.__command_configHash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns The current command configuration settings.

Returns:

  • (Hash)

    The current command configuration settings



173
174
175
# File 'lib/hati_command/befehl.rb', line 173

def __command_config
  @__command_config ||= {}
end

.execute_with_transaction_handling?Boolean

Returns:

  • (Boolean)


201
202
203
204
205
# File 'lib/hati_command/befehl.rb', line 201

def execute_with_transaction_handling?
  has_ar_defined = defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:transaction)

  !!(command_config.dig(:ar_transaction, :methods) && has_ar_defined)
end

.handle_fail_fast_error(error) ⇒ HatiCommand::Failure

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Handles fail-fast errors during command execution

Parameters:

Returns:



181
182
183
184
185
186
# File 'lib/hati_command/befehl.rb', line 181

def handle_fail_fast_error(error)
  failure_obj = error.failure_obj
  return HatiCommand::Failure.new(error, trace: error.backtrace.first) unless failure_obj

  failure_obj.tap { |err| err.trace = error.backtrace[1] }
end

.handle_standard_error(error) ⇒ HatiCommand::Failure

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Handles standard errors during command execution

Parameters:

  • error (StandardError)

    The error to handle

Returns:

Raises:

  • (StandardError)

    If no unexpected error handler is configured



193
194
195
196
197
198
199
# File 'lib/hati_command/befehl.rb', line 193

def handle_standard_error(error)
  internal_err = command_config[:unexpected_err]
  raise error unless internal_err

  err = internal_err.is_a?(TrueClass) ? error : internal_err
  HatiCommand::Failure.new(error, err: err, trace: error.backtrace.first)
end

Instance Method Details

#ar_transaction(*cmd_methods, returnable: true) ⇒ Object

WIP: experimental TODO: set of methods



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/hati_command/befehl.rb', line 84

def ar_transaction(*cmd_methods, returnable: true)
  has_ar_defined = defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:transaction)
  raise ERR::ConfigurationError, 'No ActiveRecord defined' unless has_ar_defined

  has_valid_mthds = cmd_methods.any? { |value| value.is_a?(Symbol) }
  raise ERR::ConfigurationError, 'Invalid types. Accepts Array[Symbol]' unless has_valid_mthds

  command_config[:ar_transaction] = {
    methods: cmd_methods,
    returnable: returnable
  }

  dynamic_module = Module.new do
    cmd_methods.each do |method_name|
      define_method(method_name) do |*args, **kwargs, &block|
        rez = ActiveRecord::Base.transaction do
          result = super(*args, **kwargs, &block)

          # Rollbacks to prevent partial transaction state
          if returnable && !result.is_a?(HatiCommand::Result)
            raise ERR::ConfigurationError,
                  'This command configuration requires explicit Result-return from transaction'
          end

          # Allows explicit partial commit
          if result.failure?
            raise ERR::TransactionError.new('Transaction brake has been triggered', failure_obj: result.value)
          end

          result
        end

        rez
      rescue ERR::TransactionError => e
        # TODO: process trace corectly (line of code)
        HatiCommand::Failure.new(e.failure_obj, err: e.message, trace: e.backtrace&.first)
      # Every other error including FailFast goes to main caller method
      rescue ActiveRecord::ActiveRecordError => e
        # TODO: process trace
        HatiCommand::Failure.new(e, err: e.message, trace: e.backtrace&.first)
      end
    end
  end

  prepend dynamic_module
end

#call(*args, __command_reciever: nil, **kwargs) {|Object| ... } ⇒ HatiCommand::Result, Object

Executes the command with the given arguments.

This method creates a new instance of the command class, yields it to an optional block, and then calls the instance method with the provided arguments. It handles the result of the command execution, returning a success or failure result based on the outcome.

Parameters:

  • args (Array)

    Arguments to be passed to the instance method.

Yields:

  • (Object)

    Optional block that yields the new instance for additional configuration.

Returns:

  • (HatiCommand::Result, Object)

    The result of the command, wrapped in a Result object if applicable.

Raises:



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/hati_command/befehl.rb', line 142

def call(*args, __command_reciever: nil, **kwargs, &block)
  result = caller_result(*args, __command_reciever: __command_reciever, **kwargs, &block)

  return result unless command_config[:result_inference]
  return result if result.is_a?(HatiCommand::Result)

  HatiCommand::Success.new(result)
rescue ERR::FailFastError => e
  handle_fail_fast_error(e)
rescue StandardError => e
  handle_standard_error(e)
end

#call_as(value = :call) ⇒ Symbol

This method checks if a caller method has been set; if not, it defaults to ‘:call`.

Returns:

  • (Symbol)

    The name of the method to call.



76
77
78
79
80
# File 'lib/hati_command/befehl.rb', line 76

def call_as(value = :call)
  command_config[:call_as] = value

  singleton_class.send(:alias_method, value, :call)
end

#caller_result(*args, __command_reciever: nil, **kwargs, &block) ⇒ Object

TODO: think on opts to hide reciever



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/hati_command/befehl.rb', line 156

def caller_result(*args, __command_reciever: nil, **kwargs, &block)
  # expecting pre-configured reciever if given
  if __command_reciever
    obj = __command_reciever
  else
    obj = new
    yield(obj) if !obj && block_given?
  end

  # TODO: add error if no instance method to call
  obj.send(command_config[:call_as] || :call, *args, **kwargs, &block)
end

#command {|void| ... } ⇒ Hash

Configures a command block with specific settings

Examples:

command do
  failure :my_failure_handler
  fail_fast true
end

Yields:

  • (void)

    The configuration block

Returns:

  • (Hash)

    The command configuration



37
38
39
# File 'lib/hati_command/befehl.rb', line 37

def command(&block)
  instance_eval(&block) if block_given?
end

#command_configHash

Returns The current command configuration settings.

Returns:

  • (Hash)

    The current command configuration settings



42
43
44
# File 'lib/hati_command/befehl.rb', line 42

def command_config
  __command_config
end

#fail_fast(value) ⇒ void

This method returns an undefined value.

Sets the fail-fast behavior for the command

Parameters:

  • value (Boolean)

    Whether to enable fail-fast behavior



63
64
65
# File 'lib/hati_command/befehl.rb', line 63

def fail_fast(value)
  command_config[:fail_fast] = value
end

#failure(value) ⇒ void

This method returns an undefined value.

Sets the failure handler for the command

Parameters:

  • value (Symbol, Proc)

    The failure handler to be used



56
57
58
# File 'lib/hati_command/befehl.rb', line 56

def failure(value)
  command_config[:failure] = value
end

#result_inference(value) ⇒ void

This method returns an undefined value.

Sets the result inference behavior for the command.

Parameters:

  • value (Boolean)

    Indicates whether to enable result inference.



49
50
51
# File 'lib/hati_command/befehl.rb', line 49

def result_inference(value)
  command_config[:result_inference] = value
end

#unexpected_err(value) ⇒ void

This method returns an undefined value.

Sets the unexpected error handler for the command

Parameters:

  • value (Symbol, Proc, Boolean)

    The error handler to be used



70
71
72
# File 'lib/hati_command/befehl.rb', line 70

def unexpected_err(value)
  command_config[:unexpected_err] = value
end