lib/xeroizer/http.rb in xeroizer-0.2.0 vs lib/xeroizer/http.rb in xeroizer-0.2.1

- old
+ new

@@ -62,38 +62,52 @@ if params.any? url += "?" + params.map {|key,value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"}.join("&") end uri = URI.parse(url) - - logger.info("\n== [#{Time.now.to_s}] XeroGateway Request: #{uri.request_uri} ") if self.logger - - response = case method - when :get then client.get(uri.request_uri, headers) - when :post then client.post(uri.request_uri, { :xml => body }, headers) - when :put then client.put(uri.request_uri, { :xml => body }, headers) - end - - if self.logger - logger.info("== [#{Time.now.to_s}] XeroGateway Response (#{response.code})") - - unless response.code.to_i == 200 - logger.info("== #{uri.request_uri} Response Body \n\n #{response.plain_body} \n == End Response Body") + + attempts = 0 + + begin + attempts += 1 + logger.info("\n== [#{Time.now.to_s}] XeroGateway Request: #{uri.request_uri} ") if self.logger + + response = case method + when :get then client.get(uri.request_uri, headers) + when :post then client.post(uri.request_uri, { :xml => body }, headers) + when :put then client.put(uri.request_uri, { :xml => body }, headers) end - end - - case response.code.to_i - when 200 - response.plain_body - when 400 - handle_error!(response) - when 401 - handle_oauth_error!(response) - when 404 - handle_object_not_found!(response, url) + + if self.logger + logger.info("== [#{Time.now.to_s}] XeroGateway Response (#{response.code})") + + unless response.code.to_i == 200 + logger.info("== #{uri.request_uri} Response Body \n\n #{response.plain_body} \n == End Response Body") + end + end + + case response.code.to_i + when 200 + response.plain_body + when 400 + handle_error!(response, body) + when 401 + handle_oauth_error!(response) + when 404 + handle_object_not_found!(response, url) + else + raise "Unknown response code: #{response.code.to_i}" + end + rescue Xeroizer::OAuth::RateLimitExceeded + if self.rate_limit_sleep + raise if attempts > rate_limit_max_attempts + logger.info("== Rate limit exceeded, retrying") if self.logger + sleep_for(self.rate_limit_sleep) + retry else - raise "Unknown response code: #{response.code.to_i}" + raise + end end end def handle_oauth_error!(response) error_details = CGI.parse(response.plain_body) @@ -109,11 +123,11 @@ when "rate limit exceeded" then raise OAuth::RateLimitExceeded.new(description) else raise OAuth::UnknownError.new(error_details["oauth_problem"].first + ':' + description) end end - def handle_error!(response) + def handle_error!(response, request_body) raw_response = response.plain_body # XeroGenericApplication API Exceptions *claim* to be UTF-16 encoded, but fail REXML/Iconv parsing... # So let's ignore that :) @@ -124,11 +138,12 @@ if doc.root.name == "ApiException" raise ApiException.new(doc.root.xpath("Type").text, doc.root.xpath("Message").text, - raw_response) + raw_response, + request_body) else raise "Unparseable 400 Response: #{raw_response}" @@ -140,9 +155,13 @@ case(request_url) when /Invoices/ then raise InvoiceNotFoundError.new("Invoice not found in Xero.") when /CreditNotes/ then raise CreditNoteNotFoundError.new("Credit Note not found in Xero.") else raise ObjectNotFound.new(request_url) end + end + + def sleep_for(seconds = 1) + sleep seconds end end end