class Camper::Request

Constants

MAX_RETRY_ATTEMPTS

Attributes

attempts[R]

Public Class Methods

decode(response) click to toggle source

Decodes a JSON response into Ruby object.

# File lib/camper/request.rb, line 56
def self.decode(response)
  response ? JSON.parse(response) : {}
rescue JSON::ParserError
  raise Error::Parsing, 'The response is not a valid JSON'
end
new(client, method, path, options = {}) click to toggle source
# File lib/camper/request.rb, line 26
def initialize(client, method, path, options = {})
  @client = client
  @path = path
  @options = options
  @attempts = 0
  @method = method

  self.class.headers 'User-Agent' => @client.user_agent
end
parse(body) click to toggle source

Converts the response body to a Resource.

# File lib/camper/request.rb, line 37
def self.parse(body)
  body = decode(body)

  if body.is_a? Hash
    Resource.create(body)
  elsif body.is_a? Array
    PaginatedResponse.new(body.collect! { |e| Resource.create(e) })
  elsif body
    true
  elsif !body
    false
  elsif body.nil?
    false
  else
    raise Error::Parsing, "Couldn't parse a response body"
  end
end

Public Instance Methods

execute() click to toggle source

Executes the request

# File lib/camper/request.rb, line 63
def execute
  endpoint, params = prepare_request_data

  raise Error::InvalidURL, endpoint unless UrlUtils.basecamp_url?(endpoint)
  raise Error::TooManyRetries, endpoint if maxed_attempts?

  @attempts += 1

  logger.debug("Method: #{@method}; URL: #{endpoint}")

  response, result = validate self.class.send(@method, endpoint, params)
  response = extract_parsed(response) if result == Result::VALID

  return response, result
end
maxed_attempts?() click to toggle source
# File lib/camper/request.rb, line 79
def maxed_attempts?
  @attempts >= MAX_RETRY_ATTEMPTS
end

Private Instance Methods

authorization_header() click to toggle source

Returns an Authorization header hash

@raise [Error::MissingCredentials] if access_token and auth_token are not set.

# File lib/camper/request.rb, line 136
def authorization_header
  raise Error::MissingCredentials, 'Please provide a access_token' if @client.access_token.to_s.empty?

  { 'Authorization' => "Bearer #{@client.access_token}" }
end
body_to_json?(params) click to toggle source
# File lib/camper/request.rb, line 142
def body_to_json?(params)
  %w[post put].include?(@method) && params.key?(:body)
end
extract_parsed(response) click to toggle source
# File lib/camper/request.rb, line 124
def extract_parsed(response)
  parsed = response.parsed_response

  parsed.client = @client if parsed.respond_to?(:client=)
  parsed.parse_headers!(response.headers) if parsed.respond_to?(:parse_headers!)

  parsed
end
prepare_request_data() click to toggle source
# File lib/camper/request.rb, line 85
def prepare_request_data
  params = @options.dup
  override_path = params.delete(:override_path)

  params[:body] = params[:body].to_json if body_to_json?(params)

  params[:headers] ||= {}
  params[:headers].merge!(self.class.headers)
  params[:headers].merge!(authorization_header)

  full_endpoint = override_path ? @path : @client.api_endpoint + @path

  full_endpoint = UrlUtils.transform(full_endpoint)

  return full_endpoint, params
end
validate(response) click to toggle source

Checks the response code for common errors. Informs that a retry needs to happen if request failed due to access token expiration @raise [Error::ResponseError] if response is an HTTP error @return [Response, Request::Result]

# File lib/camper/request.rb, line 106
def validate(response)
  error_klass = Error::STATUS_MAPPINGS[response.code]

  if error_klass == Error::Unauthorized && response.parsed_response.error.include?('OAuth token expired (old age)')
    logger.debug('Access token expired. Please obtain a new access token')
    return response, Result::ACCESS_TOKEN_EXPIRED
  end

  if error_klass == Error::TooManyRequests
    logger.debug('Too many request. Please check the Retry-After header for subsequent requests')
    return response, Result::TOO_MANY_REQUESTS
  end

  raise error_klass, response if error_klass

  return response, Result::VALID
end