Module: Aikido::Zen::Sinks::DSL

Extended by:
DSL
Included in:
DSL
Defined in:
lib/aikido/zen/sinks_dsl.rb

Defined Under Namespace

Classes: PresafeError

Instance Method Summary collapse

Instance Method Details

#presafe { ... } ⇒ Object

Presafely execute the given block

Safely wrap standard errors in ‘PresafeError` so that the original error is reraised when rescued in `safe`.

Yields:

  • the block to execute



96
97
98
99
100
# File 'lib/aikido/zen/sinks_dsl.rb', line 96

def presafe
  yield
rescue => err
  raise PresafeError, cause: err
end

#presafe_sink_after(method_name) {|result, args, kwargs| ... } ⇒ void

This method returns an undefined value.

Define a method ‘method_name` that presafely executes the given block after the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute after the original method

Yield Parameters:

  • result (Object)

    the result returned by the original method

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method



155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/aikido/zen/sinks_dsl.rb', line 155

def presafe_sink_after(method_name, &block)
  raise ArgumentError, "block required" unless block

  original = instance_method(method_name)

  define_method(method_name) do |*args, **kwargs, &blk|
    result = original.bind_call(self, *args, **kwargs, &blk)
    instance_exec(result, *args, **kwargs, &block)
    result
  end
rescue NameError
  Aikido::Zen.config.logger.warn("cannot wrap method `#{method_name}' for class `#{self}'")
end

#presafe_sink_around(method_name) {|original_call, args, kwargs| ... } ⇒ void

This method returns an undefined value.

Define a method ‘method_name` that presafely executes the given block around the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute around the original method

Yield Parameters:

  • original_call (Proc)

    the proc that calls the original method

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/aikido/zen/sinks_dsl.rb', line 201

def presafe_sink_around(method_name, &block)
  raise ArgumentError, "block required" unless block

  original = instance_method(method_name)

  define_method(method_name) do |*args, **kwargs, &blk|
    result = nil
    original_call = proc do
      result = original.bind_call(self, *args, **kwargs, &blk)
    end
    instance_exec(original_call, *args, **kwargs, &block)
    result
  end
rescue NameError
  Aikido::Zen.config.logger.warn("cannot wrap method `#{method_name}' for class `#{self}'")
end

#presafe_sink_before(method_name) {|args, kwargs| ... } ⇒ void

This method returns an undefined value.

Define a method ‘method_name` that presafely executes the given block before the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute before the original method

Yield Parameters:

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/aikido/zen/sinks_dsl.rb', line 111

def presafe_sink_before(method_name, &block)
  raise ArgumentError, "block required" unless block

  original = instance_method(method_name)

  define_method(method_name) do |*args, **kwargs, &blk|
    instance_exec(*args, **kwargs, &block)
    original.bind_call(self, *args, **kwargs, &blk)
  end
rescue NameError
  Aikido::Zen.config.logger.warn("cannot wrap method `#{method_name}' for class `#{self}'")
end

#safe { ... } ⇒ Object

Safely execute the given block

All standard errors are suppressed except ‘Aikido::Zen::UnderAttackError`s. This ensures that unexpected errors do not interrupt the execution of the original method, while all detected attacks are raised.

When an error is wrapped in ‘PresafeError` the original error is reraised.

Yields:

  • the block to execute



80
81
82
83
84
85
86
87
88
# File 'lib/aikido/zen/sinks_dsl.rb', line 80

def safe
  yield
rescue Aikido::Zen::UnderAttackError
  raise
rescue PresafeError => err
  raise err.cause
rescue => err
  Aikido::Zen.config.logger.debug("[safe] #{err.class}: #{err.message}")
end

#sink_after(method_name) {|result, args, kwargs| ... } ⇒ void

Note:

the block is executed within ‘safe` to handle errors safely; the original method is executed outside of `safe` to preserve the original behavior

This method returns an undefined value.

Define a method ‘method_name` that safely executes the given block after the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute after the original method

Yield Parameters:

  • result (Object)

    the result returned by the original method

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method

Raises:

  • (ArgumentError)


181
182
183
184
185
186
187
188
189
# File 'lib/aikido/zen/sinks_dsl.rb', line 181

def sink_after(method_name, &block)
  raise ArgumentError, "block required" unless block

  presafe_sink_after(method_name) do |result, *args, **kwargs|
    DSL.safe do
      instance_exec(result, *args, **kwargs, &block)
    end
  end
end

#sink_around(method_name) {|original_call, args, kwargs| ... } ⇒ void

Note:

the block is executed within ‘safe` to handle errors safely; the original method is executed within `presafe` to preserve the original behavior

Note:

if the block does not call ‘original_call`, the original method is called automatically after the block is executed

This method returns an undefined value.

Define a method ‘method_name` that safely executes the given block around the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute around the original method

Yield Parameters:

  • original_call (Proc)

    the proc that calls the original method

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method

Raises:

  • (ArgumentError)


231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/aikido/zen/sinks_dsl.rb', line 231

def sink_around(method_name, &block)
  raise ArgumentError, "block required" unless block

  presafe_sink_around(method_name) do |presafe_original_call, *args, **kwargs|
    original_called = false
    original_call = proc do
      original_called = true
      DSL.presafe do
        presafe_original_call.call
      end
    end
    DSL.safe do
      instance_exec(original_call, *args, **kwargs, &block)
    end
    presafe_original_call.call unless original_called
  end
end

#sink_before(method_name) {|args, kwargs| ... } ⇒ void

Note:

the block is executed within ‘safe` to handle errors safely; the original method is executed outside of `safe` to preserve the original behavior

This method returns an undefined value.

Define a method ‘method_name` that safely executes the given block before the original method.

Parameters:

  • method_name (Symbol, String)

    the name of the method to define

Yields:

  • the block to execute before the original method

Yield Parameters:

  • args (Array)

    the positional arguments passed to the original method

  • kwargs (Hash)

    the keyword arguments passed to the original method

Raises:

  • (ArgumentError)


135
136
137
138
139
140
141
142
143
# File 'lib/aikido/zen/sinks_dsl.rb', line 135

def sink_before(method_name, &block)
  raise ArgumentError, "block required" unless block

  presafe_sink_before(method_name) do |*args, **kwargs|
    DSL.safe do
      instance_exec(*args, **kwargs, &block)
    end
  end
end