Skip to content

Commit

Permalink
Handle ShipperAccount updates
Browse files Browse the repository at this point in the history
  • Loading branch information
krzyzak committed Mar 21, 2017
1 parent a2ec5ee commit 334a3dc
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 47 deletions.
95 changes: 55 additions & 40 deletions lib/postmen/connection.rb
Expand Up @@ -22,45 +22,10 @@ def initialize
# @example
# .get('/labels')
# .get('/labels', { params: { limit: 5 } })
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def get(path, options = {})
Response.new(raw_get(path, options)).tap(&:parse_response!)
# Rescue from any connection issues
rescue HTTP::ConnectionError
# Raise error if we already tried to use failover domain
raise if Postmen.failover?
# Switch to failover domain & retry the request
Postmen.failover!
retry
# Handle Rate limits.
# Rate limits are being reset every 60 seconds - we're retrying
# given request after that.
# @see https://docs.postmen.com/ratelimit.html Documentation
rescue RateLimitExceeded
@requests += 1
raise if @requests > MAX_REQUESTS
sleep(60)
retry
# If the resource was not found, simply re-raise the exception
rescue ResourceNotFound
raise
# Handle request errors.
# Our current error handling policy depends on the error type.
# If the API returns information, that the request is retriable,
# We're waiting 5 seconds, and trying again with exact same request.
# To prevent having infinite loops, we're trying maximum 5 times.
# In case that we were unable to make successfull request with that 5 tries,
# MaximumNumberOfRetriesReachedError is being raised.
#
# @raise RequestError if the request is not retriable
# @raise MaximumNumberOfRetriesReachedError if the API returned error after 5 retries
rescue RequestError => error
raise unless error.retriable?
raise MaximumNumberOfRetriesReachedError, self if @requests > MAX_REQUESTS
@requests += 1
sleep(5)
retry
with_error_handling do
Response.new(raw_get(path, options)).tap(&:parse_response!)
end
end

# Performs a HTTP POST request.
Expand All @@ -71,7 +36,9 @@ def get(path, options = {})
# .post('/labels')
# .post('/labels', { json: { my: { sample: :data } } })
def post(path, options = {})
Response.new(raw_post(path, options))
with_error_handling do
Response.new(raw_post(path, options))
end
end

# Performs a HTTP PUT request.
Expand All @@ -82,7 +49,9 @@ def post(path, options = {})
# .put('/shipper-accounts/123/info')
# ..put('/shipper-accounts/123/info', { json: { my: { sample: :data } } })
def put(path, options = {})
Response.new(raw_put(path, options))
with_error_handling do
Response.new(raw_put(path, options)).tap(&:parse_response!)
end
end

# Performs a HTTP DELETE request
Expand Down Expand Up @@ -118,6 +87,52 @@ def self.hostname(subdomain, failover)

private

# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity
def with_error_handling
raise ArgumentError unless block_given?

begin
yield
# Rescue from any connection issues
rescue HTTP::ConnectionError
# Raise error if we already tried to use failover domain
raise if Postmen.failover?
# Switch to failover domain & retry the request
Postmen.failover!
retry
# Handle Rate limits.
# Rate limits are being reset every 60 seconds - we're retrying
# given request after that.
# @see https://docs.postmen.com/ratelimit.html Documentation
rescue RateLimitExceeded
@requests += 1
raise if @requests > MAX_REQUESTS
sleep(60)
retry
# If the resource was not found, simply re-raise the exception
rescue ResourceNotFound
raise
# Handle request errors.
# Our current error handling policy depends on the error type.
# If the API returns information, that the request is retriable,
# We're waiting 5 seconds, and trying again with exact same request.
# To prevent having infinite loops, we're trying maximum 5 times.
# In case that we were unable to make successfull request with that 5 tries,
# MaximumNumberOfRetriesReachedError is being raised.
#
# @raise RequestError if the request is not retriable
# @raise MaximumNumberOfRetriesReachedError if the API returned error after 5 retries
rescue RequestError => error
raise unless error.retriable?
raise MaximumNumberOfRetriesReachedError, self if @requests > MAX_REQUESTS
@requests += 1
sleep(5)
retry
end
end

def raw_get(path, options)
HTTP
.headers(headers)
Expand Down
2 changes: 1 addition & 1 deletion lib/postmen/errors.rb
Expand Up @@ -6,7 +6,7 @@ class Postmen
class RequestError < Error
extend Forwardable

def_delegators :@request, :meta
def_delegators :@request, :meta, :data

def initialize(request)
@request = request
Expand Down
12 changes: 12 additions & 0 deletions lib/postmen/response.rb
Expand Up @@ -16,12 +16,24 @@ def meta
@meta ||= parsed_response[:meta]
end

# Holds the data
# @see https://docs.postmen.com/#data API Documentation
# @return [Hash]
def data
@data ||= parsed_response[:data]
end

# Parses the json response
# @return [Hash]
def parsed_response
@parsed_response ||= JSON.parse(body, symbolize_names: true)
end

# Checks if response were successfull
def success?
meta[:code] == 200
end

# Checks if rate limit was exceeded
def rate_limit_exceeded?
code == 429
Expand Down
45 changes: 40 additions & 5 deletions lib/postmen/shipper_account.rb
Expand Up @@ -47,11 +47,27 @@ def destroy
#
# @see https://docs.postmen.com/api.html#shipper-accounts-update-a-shipper-account-credentials
# @return [ShipperAccount] Updated ShipperAccount resource
def update_credentials(params = {})
Connection.new.put(
# @raise [RequestError]
def update_credentials!(params = {})
response = Connection.new.put(
"/shipper-accounts/#{@id}/credentials",
ShipperAccountUpdateCredentialsQuery.new(params).to_hash
ShipperAccountUpdateCredentialsQuery.new(params).to_query
)

raise RequestError, response unless response.success?

ShipperAccount.new(response.data)
end

# Update a ShipperAccount credentials
#
# @see https://docs.postmen.com/api.html#shipper-accounts-update-a-shipper-account-credentials
# @return [ShipperAccount] Updated ShipperAccount resource
# @return [Hash] a Hash with detailed information about what went wrong
def update_credentials(params = {})
update_credentials!(params)
rescue RequestError => error
error.meta
end

# Update a shipper account information
Expand All @@ -61,11 +77,30 @@ def update_credentials(params = {})
# .update(description: "Your new description")
# .update(address: {})
# @return [ShipperAccount] Updated ShipperAccount resource
def update(params = {})
Connection.new.put(
# @raise [RequestError]
def update!(params = {})
response = Connection.new.put(
"/shipper-accounts/#{@id}/info",
ShipperAccountUpdateQuery.new(params.merge(subject: self)).to_query
)

raise RequestError, response unless response.success?

ShipperAccount.new(response.data)
end

# Update a shipper account information
#
# @see https://docs.postmen.com/api.html#shipper-accounts-update-a-shipper-account-information API Documentation
# @example
# .update(description: "Your new description")
# .update(address: {})
# @return [ShipperAccount] Updated ShipperAccount resource
# @return [Hash] a Hash with detailed information about what went wrong
def update(params = {})
update!(params)
rescue RequestError => error
error.meta
end
end
end
2 changes: 1 addition & 1 deletion lib/postmen/version.rb
@@ -1,4 +1,4 @@
class Postmen
# SDK Version
VERSION = '1.0.0-alpha.1'.freeze
VERSION = '1.0.0-alpha.2'.freeze
end

0 comments on commit 334a3dc

Please sign in to comment.