class Darwinex::Api::Api

Attributes

logger[R]

Public Class Methods

new(logger) click to toggle source
# File lib/darwinex/api/api.rb, line 12
def initialize(logger)
  @logger = logger
end

Public Instance Methods

send(http_method, path, options, max_retries:) click to toggle source
# File lib/darwinex/api/api.rb, line 16
def send(http_method, path, options, max_retries:)
  response = backoff_and_retry(http_method, path, options, max_retries: max_retries)

  response.parsed_response
end

Private Instance Methods

backoff_and_retry(http_method, path, options, max_retries:) click to toggle source
# File lib/darwinex/api/api.rb, line 26
def backoff_and_retry(http_method, path, options, max_retries:)
  retries = 0

  begin
    response = self.class.public_send(http_method, path, options)

    parse_response_for_errors(response)

    response
  rescue Errno::ECONNREFUSED, Net::ReadTimeout, ThrottledError => e
    if retries < max_retries
      retries += 1
      backoff_time = 2**retries

      logger.warn("#{e.message} - backing off for #{backoff_time} seconds")

      sleep backoff_time
      retry
    else
      raise e
    end
  end
end
parse_response_for_errors(response) click to toggle source
# File lib/darwinex/api/api.rb, line 50
def parse_response_for_errors(response)
  # Darwinex need to be more consistent with their API responses :(

  unless response.success?
    body = response.parsed_response

    if body['error'] == 'invalid_grant'
      msg = body['error_description']
      raise RefreshTokenExpiredError.new(msg, response)
    end

    if body.dig('fault', 'message') == 'Invalid Credentials'
      msg = body['fault']['description']
      raise InvalidCredentialsError.new(msg, response)
    end

    if body.dig('fault', 'message') == 'Message throttled out'
      msg = body['fault']['description']
      raise ThrottledError.new(msg, response)
    end

    if !body['status'].nil?
      msg = body['status']
    elsif !body['error_description'].nil?
      msg = body['error_description']
    elsif !body.dig('fault', 'description').nil?
      msg = body['fault']['description']
    end

    raise Error.new(msg, response: response)
  end
end