lib/billomat/gateway.rb in billomat-0.2.0 vs lib/billomat/gateway.rb in billomat-0.3.0

- old
+ new

@@ -2,20 +2,36 @@ require 'rest-client' require 'json' module Billomat - ## - # Raised if something goes wrong during an API call - class GatewayError < StandardError; end + # Raised if something goes wrong during an API call. + class GatewayError < StandardError + attr_reader :original_exception - ## - # This class can be used by the gem to communicate with the API + # Create a new GatewayError from a RestClient exception. + # + # @param original_exception [RestClient::Exception] the original exception + def initialize(original_exception) + # Extract the error from the response if it is present. If no error + # could be extracted, use the whole body + body = original_exception.response&.body + response_error = JSON.parse(body).dig('errors', 'error') || body if body + + # Use the default message and append our detailed error + message = original_exception.default_message + message += " ('#{response_error}')" if response_error + + super(message) + @original_exception = original_exception + end + end + + # This class can be used by the gem to communicate with the API. class Gateway attr_reader :method, :path, :body - ## # Creates a new Gateway # # @param [Symbol] method The HTTP verb # @param [String] path The path of the resource # @param [Hash] body The payload for the request @@ -27,53 +43,57 @@ @method = method.to_sym @path = path @body = body end - ## - # Executes the API call - # @return [Hash] The response body + # Executes the API call and parse the response. + # + # @return [Hash] the response body def run resp = response - raise GatewayError, resp.body if resp.code > 299 return nil if resp.body.empty? JSON.parse(resp.body) + rescue RestClient::Exception => e + raise GatewayError, e end + # Executes the API call and return the response. + # + # @return [RestClient::Response] the API response def response RestClient::Request.execute( - method: method, - url: url, - timeout: timeout, - headers: headers, - payload: body.to_json + method: method, + url: url, + timeout: timeout, + headers: headers, + payload: body.to_json ) end - # @return [String] The complete URL for the request + # @return [String] the complete URL for the request def url "https://#{config.subdomain}.billomat.net/api#{path}" end # @return [Integer] def timeout config.timeout || 5 end - # @return [Hash] The headers for the request. + # @return [Hash] the headers for the request def headers { - 'Accept' => 'application/json', - 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', 'X-BillomatApiKey' => config.api_key, - 'X-AppId' => config.app_id, - 'X-AppSecret' => config.app_secret + 'X-AppId' => config.app_id, + 'X-AppSecret' => config.app_secret }.reject { |_, val| val.nil? } end - # @return [Billomat::Configuration] The global gem configuration + # @return [Billomat::Configuration] the global gem configuration # # :reek:UtilityFunction because it's a shorthand def config Billomat.configuration end