Module: Ignorable Private

Includes:
Kernel
Defined in:
ignorable.rb,
ignorable.rbi

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Defined Under Namespace

Modules: ExceptionMixin

Constant Summary

Constants included from Kernel

Kernel::IGNORE_INTERRUPTS_MUTEX

Class Method Summary collapse

Methods included from Kernel

#ensure_executable!, #exec_browser, #exec_editor, #ignore_interrupts, #interactive_shell, #quiet_system, #redirect_stdout, #safe_system, #which, #which_editor, #with_env, #with_homebrew_path

Class Method Details

.hook_raise(on_ignorable:, &block) ⇒ T.type_parameter(:U)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Runs the block in a Fiber whose raise pauses at the raise site and passes the exception to on_ignorable. If it returns :ignore, execution resumes after the raise site, otherwise the exception is raised there as usual.

Parameters:

  • on_ignorable (T.proc.params(exception: Exception).returns(Symbol))
  • block (T.proc.returns(T.type_parameter(:U)))

Returns:

  • (T.type_parameter(:U))


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'ignorable.rb', line 20

def self.hook_raise(on_ignorable:, &block)
  fiber = Fiber.new(&block)

  Object.class_eval do
    # `define_method` keeps Sorbet happy inside this `class_eval` block.
    define_method(:raise) do |*args, **kwargs|
      super(*args, **kwargs)
    # All possible exceptions must be pausable, not just `StandardError`.
    rescue Exception => e # rubocop:disable Lint/RescueException
      if e.is_a?(ScriptError) || Fiber.current != fiber
        super(e)
      else
        e.extend(ExceptionMixin)
        super(e) if Fiber.yield(e) != :ignore
      end
    end

    alias_method :fail, :raise
  end

  result = fiber.resume
  while fiber.alive?
    decision = begin
      on_ignorable.call(result)
    # Even `Interrupt` at the prompt must unwind the fiber, not abandon it.
    rescue Exception => e # rubocop:disable Lint/RescueException
      e
    end

    result = case decision
    when :ignore then fiber.resume(:ignore)
    # Raise inside the fiber so its `ensure` blocks and rescues still run.
    when Exception then fiber.raise(decision)
    else fiber.resume(:raise)
    end
  end
  result
ensure
  Object.class_eval do
    remove_method(:raise)
    remove_method(:fail)
  end
end

.raiseObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This is a workaround to enable raise to be aliased



8
# File 'ignorable.rbi', line 8

def self.raise(*); end