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::UnderAttackErrors. 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