module GraphQL::Execution::Instrumentation

def call_hooks(instrumenters, object, before_hook_name, after_hook_name)

If they don't all succeed, call after_ for each one that succeeded.
Call each before hook, and if they all succeed, yield.
def call_hooks(instrumenters, object, before_hook_name, after_hook_name)
  begin
    successful = []
    instrumenters.each do |instrumenter|
      instrumenter.public_send(before_hook_name, object)
      successful << instrumenter
    end
    # if any before hooks raise an exception, quit calling before hooks,
    # but call the after hooks on anything that succeeded but also
    # raise the exception that came from the before hook.
  rescue GraphQL::ExecutionError => err
    object.context.errors << err
  rescue => e
    raise call_after_hooks(successful, object, after_hook_name, e)
  end
  begin
    yield # Call the user code
  ensure
    ex = call_after_hooks(successful, object, after_hook_name, nil)
    raise ex if ex
  end
end