Module: Whiplash::App::Connections

Included in:
Whiplash::App
Defined in:
lib/whiplash/app/connections.rb

Instance Method Summary collapse

Instance Method Details

#app_request(options = {}) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/whiplash/app/connections.rb', line 25

def app_request(options={})
  return base_app_request(options) unless defined?(Sidekiq)
  limiter = Sidekiq::Limiter.window('whiplash-core', self.rate_limit, :second, wait_timeout: 15)
  limiter.within_limit do
    base_app_request(options)
  end
end

#app_request!(options = {}) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/whiplash/app/connections.rb', line 33

def app_request!(options = {})
  begin
    response = app_request(options)
    return response if response.success?
    message = response.body if response.body.is_a? String
    message = response.body.dig('error') if response.body.respond_to?(:dig)
    store_whiplash_error!(response.status)
    error_response(response.status, message)
  rescue Faraday::ConnectionFailed => e
    case e.message
    when 'end of file reached'
      store_whiplash_error!(:eof, options)
      Rails.logger.error "[Whiplash][EOF] Failed to connect to #{url}"
      raise ProviderError::InternalServerError, e.message
    when 'Net::OpenTimeout'
      store_whiplash_error!(:timeout, options)
      Rails.logger.error "[Whiplash][Timeout] Request to #{url} timed out"
      raise ProviderError::Timeout, e.message
    else
      store_whiplash_error!(:connection, options)
      Rails.logger.error "[Whiplash] Request to #{url} failed"
      raise ProviderError::InternalServerError, e.message
    end
  end
end

#base_app_request(options = {}) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/whiplash/app/connections.rb', line 5

def base_app_request(options={})
  if options[:params][:id]
    endpoint = [options[:endpoint], options[:params].delete(:id)].join('/')
  else
    endpoint = options[:endpoint]
  end
  options[:headers] ||= {}
  options[:headers][:customer_id] ||= customer_id if customer_id
  options[:headers][:shop_id] ||= shop_id if shop_id

  args = [
    options[:method],
    endpoint,
    options[:params],
    sanitize_headers(options[:headers])
  ]

  connection.send(*args)
end

#delete(endpoint, params = {}, headers = nil) ⇒ Object



59
60
61
62
63
64
# File 'lib/whiplash/app/connections.rb', line 59

def delete(endpoint, params = {}, headers = nil)
  app_request(method: :delete,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#delete!(endpoint, params = {}, headers = nil) ⇒ Object



87
88
89
90
91
92
# File 'lib/whiplash/app/connections.rb', line 87

def delete!(endpoint, params = {}, headers = nil)
  app_request!(method: :delete,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#error_codesObject



168
169
170
# File 'lib/whiplash/app/connections.rb', line 168

def error_codes
  WhiplashApiError.codes
end

#error_response(status_code, message = nil) ⇒ Object

Select an applicable error message on a request to a provider.

Raises:



181
182
183
184
# File 'lib/whiplash/app/connections.rb', line 181

def error_response(status_code, message=nil)
  message ||= "Your request has been denied as a #{status_code} error"
  raise select_error(status_code), message
end

#get(endpoint, params = {}, headers = nil) ⇒ Object



66
67
68
69
70
71
# File 'lib/whiplash/app/connections.rb', line 66

def get(endpoint, params = {}, headers = nil)
  app_request(method: :get,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#get!(endpoint, params = {}, headers = nil) ⇒ Object



94
95
96
97
98
99
# File 'lib/whiplash/app/connections.rb', line 94

def get!(endpoint, params = {}, headers = nil)
  app_request!(method: :get,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#get_body_or_empty(endpoint, params = {}, headers = nil) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/whiplash/app/connections.rb', line 115

def get_body_or_empty(endpoint, params = {}, headers = nil)
  response = get(endpoint, params, headers)
  if !response.success?
    case response.status
    when 500
      Appsignal.send_error(WhiplashApiError::InternalServerError.new(response.body), {raised: false})
    else
    end

    case get_context(endpoint)
    when 'collection'
      Rails.logger.info "[WhiplashApi] Returned #{response.status}. Returning an empty array..."
      return []
    when 'member'
      Rails.logger.info "[WhiplashApi] Returned #{response.status}. Returning nil..."
      return nil
    when 'aggregate'
      Rails.logger.info "[WhiplashApi] Returned #{response.status}. Returning an empty hash..."
      return {}
    end
  end
  response.body
end

#get_context(endpoint) ⇒ Object



139
140
141
142
143
144
# File 'lib/whiplash/app/connections.rb', line 139

def get_context(endpoint)
  parts = endpoint.split('/').compact
  return 'member' if (parts.last =~ /\d+/).present?
  return 'aggregate' if parts.include?('aggregate')
  'collection'
end

#post(endpoint, params = {}, headers = nil) ⇒ Object



73
74
75
76
77
78
# File 'lib/whiplash/app/connections.rb', line 73

def post(endpoint, params = {}, headers = nil)
  app_request(method: :post,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#post!(endpoint, params = {}, headers = nil) ⇒ Object



101
102
103
104
105
106
# File 'lib/whiplash/app/connections.rb', line 101

def post!(endpoint, params = {}, headers = nil)
  app_request!(method: :post,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#put(endpoint, params = {}, headers = nil) ⇒ Object



80
81
82
83
84
85
# File 'lib/whiplash/app/connections.rb', line 80

def put(endpoint, params = {}, headers = nil)
  app_request(method: :put,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#put!(endpoint, params = {}, headers = nil) ⇒ Object



108
109
110
111
112
113
# File 'lib/whiplash/app/connections.rb', line 108

def put!(endpoint, params = {}, headers = nil)
  app_request!(method: :put,
              endpoint: endpoint,
              params: params,
              headers: headers)
end

#sanitize_headers(headers) ⇒ Object



146
147
148
149
150
151
152
153
154
# File 'lib/whiplash/app/connections.rb', line 146

def sanitize_headers(headers)
  if headers
    {}.tap do |hash|
      headers.each do |k,v|
        hash["X-#{k.to_s.upcase.gsub('_','-')}"] = v.to_s
      end
    end
  end
end

#select_error(status_code) ⇒ Object



172
173
174
175
176
177
178
# File 'lib/whiplash/app/connections.rb', line 172

def select_error(status_code)
  unless error_codes.keys.include? status_code
    Rails.logger.info "[Provider] Unknown status code from #{self.class.name}: #{status_code}"
    return WhiplashApiError::UnknownError
  end
  error_codes[status_code]
end

#store_whiplash_error!(error, options = {}) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/whiplash/app/connections.rb', line 156

def store_whiplash_error!(error, options={})
  return unless defined?(Appsignal)
  options = options.with_indifferent_access
  Appsignal.increment_counter(
    "whiplash_error",
    1.0,
    shop_id: options[:shop_id],
    customer_id: options[:customer_id],
    error: error.to_s
  )
end