class LucidShopify::SendRequest

Public Class Methods

new(http: Container[:http], strategy: ->(*, &block) { block.() } click to toggle source

@param http [HTTP::Client] @param strategy [#call, nil] unthrottled by default

# File lib/lucid_shopify/send_request.rb, line 18
def initialize(http: Container[:http],
               strategy: ->(*, &block) { block.() })
  @http = http
  @strategy = strategy
end

Public Instance Methods

call(request, attempts: default_attempts) click to toggle source

@param request [Request] @param attempts [Integer] additional request attempts on client error

@return [Hash] the parsed response body

@raise [NetworkError] if the request failed all attempts @raise [Response::ClientError] for status 4xx @raise [Response::ServerError] for status 5xx

# File lib/lucid_shopify/send_request.rb, line 34
def call(request, attempts: default_attempts)
  req = request

  log_request(req)

  res = @strategy.(req) do
    res = send(req)

    Response.new(req, res.code, res.headers.to_h, res.to_s)
  end

  log_response(req, res)

  res.assert!
rescue HTTP::ConnectionError,
       HTTP::ResponseError,
       HTTP::TimeoutError => e
  raise NetworkError.new(e), e.message if attempts.zero?

  call(req, attempts: attempts - 1)
rescue Response::ClientError => e
  raise e unless e.response.status_code == 429

  sleep(e.response.headers['Retry-After']&.to_f || 0)

  call(req, attempts: attempts)
end
log_request(request) click to toggle source

@param request [Request]

# File lib/lucid_shopify/send_request.rb, line 76
def log_request(request)
  req = request

  LucidShopify.config.logger.info('<%s> [%i] %s %s %s' % [
    self.class.to_s,
    req.object_id,
    req.http_method.to_s.upcase,
    req.url,
    req.options[:params]&.to_json || '{}',
  ])
end
log_response(request, response) click to toggle source

@param request [Request] @param response [Response]

# File lib/lucid_shopify/send_request.rb, line 92
def log_response(request, response)
  req = request
  res = response

  LucidShopify.config.logger.info('<%s> [%i] %i (%s)' % [
    self.class.to_s,
    req.object_id,
    res.status_code,
    res.headers['X-Shopify-Shop-Api-Call-Limit'],
  ])
end

Private Instance Methods

default_attempts() click to toggle source

@return [Integer]

# File lib/lucid_shopify/send_request.rb, line 107
        def default_attempts
  3
end
send(request) click to toggle source

@param request [Request]

@return [HTTP::Response]

# File lib/lucid_shopify/send_request.rb, line 67
        def send(request)
  req = request

  @http.headers(req.http_headers).__send__(req.http_method, req.url, req.options)
end