whiplash-app 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5b252f73755dcd2e6cc7d907d0009393a0661993
4
- data.tar.gz: d38c18badde2221b2c9de962db701ca54a486739
2
+ SHA256:
3
+ metadata.gz: f5d805e2893ed8f2276b6beb9cb3803784466eed89cbe8526b0322b552c56cb6
4
+ data.tar.gz: '04628b22e8d4d2ac908c7f3f8fd2d2e70d37e209708a55e329add9ec59f2c195'
5
5
  SHA512:
6
- metadata.gz: ae66c0ded848674943ad97c2781236569d4d3cfff515ad30218b7025028660ce0cf10374f243d516b553781ca3a023460ca4b25e21713225b0a135c3ec6708cb
7
- data.tar.gz: '04845cdd6a2eb36c1f05b43932f11bf25c6d32d0c91fbb74db2cb7f23b5ca9d84d3f8719fe58926831a4d26c1c07119aa03d3b74a92b7f1528f706fa169b37f1'
6
+ metadata.gz: c9b01590969f01f35c5b7c153df98b553cac683dfa3b0cbfeb1f428fa9844a0824f3c6c8294ef40342689579eec5b8c47907945ee7c3808d7188acdec5f4ee1f
7
+ data.tar.gz: 9bda8b451dd1ba823d906b54f11b023cf2bef90ba6c21bd1533eb4083d84f8f7258f4a084c6b58a2bd6e49d5d9cfe748a08f9648815dddcbb07f48ba66b1684d
@@ -0,0 +1,94 @@
1
+ class WhiplashApiError < StandardError
2
+ class Deadlock < WhiplashApiError
3
+ end
4
+
5
+ class Timeout < WhiplashApiError
6
+ end
7
+
8
+ class Configuration < WhiplashApiError
9
+ end
10
+
11
+ class Inventory < WhiplashApiError
12
+ end
13
+
14
+ class Ignore < WhiplashApiError
15
+ end
16
+
17
+ # 400
18
+ class BadRequest < WhiplashApiError
19
+ end
20
+
21
+ # 401
22
+ class Unauthorized < WhiplashApiError
23
+ end
24
+
25
+ # 403
26
+ class Forbidden < WhiplashApiError
27
+ end
28
+
29
+ # 404
30
+ class RecordNotFound < WhiplashApiError
31
+ end
32
+
33
+ # 405
34
+ class MethodNotAllowed < WhiplashApiError
35
+ end
36
+
37
+ # 406
38
+ class NotAcceptable < WhiplashApiError
39
+ end
40
+
41
+ # 408
42
+ class Timeout < WhiplashApiError
43
+ end
44
+
45
+ # 409
46
+ class Conflict < WhiplashApiError
47
+ end
48
+
49
+ # 415
50
+ class UnsupportedMediaType < WhiplashApiError
51
+ end
52
+
53
+ # 422
54
+ class UnprocessableEntity < WhiplashApiError
55
+ end
56
+
57
+ # 429
58
+ class OverRateLimit < WhiplashApiError
59
+ end
60
+
61
+ class SSLError < WhiplashApiError
62
+ end
63
+
64
+ # 500+
65
+ class InternalServerError < WhiplashApiError
66
+ end
67
+
68
+ # 503
69
+ class ServiceUnavailable < WhiplashApiError
70
+ end
71
+
72
+ # ???
73
+ class UnknownError < WhiplashApiError
74
+ end
75
+
76
+ def self.codes
77
+ {
78
+ 400 => WhiplashApiError::BadRequest,
79
+ 401 => WhiplashApiError::Unauthorized,
80
+ 403 => WhiplashApiError::Forbidden,
81
+ 404 => WhiplashApiError::RecordNotFound,
82
+ 405 => WhiplashApiError::MethodNotAllowed,
83
+ 406 => WhiplashApiError::NotAcceptable,
84
+ 408 => WhiplashApiError::Timeout,
85
+ 409 => WhiplashApiError::Conflict,
86
+ 415 => WhiplashApiError::UnsupportedMediaType,
87
+ 422 => WhiplashApiError::UnprocessableEntity,
88
+ 429 => WhiplashApiError::OverRateLimit,
89
+ 495 => WhiplashApiError::SSLError,
90
+ 500 => WhiplashApiError::InternalServerError,
91
+ 503 => WhiplashApiError::ServiceUnavailable
92
+ }
93
+ end
94
+ end
@@ -18,6 +18,10 @@ module Whiplash
18
18
  ENV["WHIPLASH_API_URL"] || "https://sandbox.getwhiplash.com"
19
19
  end
20
20
 
21
+ def rate_limit
22
+ ENV['WHIPLASH_RATE_LIMIT'] || 25
23
+ end
24
+
21
25
  end
22
26
  end
23
27
  end
@@ -2,7 +2,7 @@ module Whiplash
2
2
  class App
3
3
  module Connections
4
4
 
5
- def app_request(options = {})
5
+ def base_app_request(options={})
6
6
  if options[:params][:id]
7
7
  endpoint = [options[:endpoint], options[:params].delete(:id)].join('/')
8
8
  else
@@ -11,10 +11,49 @@ module Whiplash
11
11
  options[:headers] ||= {}
12
12
  options[:headers][:customer_id] ||= customer_id if customer_id
13
13
  options[:headers][:shop_id] ||= shop_id if shop_id
14
- connection.send(options[:method],
15
- endpoint,
16
- options[:params],
17
- sanitize_headers(options[:headers]))
14
+
15
+ args = [
16
+ options[:method],
17
+ endpoint,
18
+ options[:params],
19
+ sanitize_headers(options[:headers])
20
+ ]
21
+
22
+ connection.send(*args)
23
+ end
24
+
25
+ def app_request(options={})
26
+ return base_app_request(options) unless defined?(Sidekiq)
27
+ limiter = Sidekiq::Limiter.window('whiplash-core', self.rate_limit, :second, wait_timeout: 15)
28
+ limiter.within_limit do
29
+ base_app_request(options)
30
+ end
31
+ end
32
+
33
+ def app_request!(options = {})
34
+ begin
35
+ app_request(options)
36
+ rescue Faraday::ConnectionFailed => e
37
+ case e.message
38
+ when 'end of file reached'
39
+ store_whiplash_error!(:eof, options)
40
+ Rails.logger.error "[Whiplash][EOF] Failed to connect to #{url}"
41
+ raise ProviderError::InternalServerError, e.message
42
+ when 'Net::OpenTimeout'
43
+ store_whiplash_error!(:timeout, options)
44
+ Rails.logger.error "[Whiplash][Timeout] Request to #{url} timed out"
45
+ raise ProviderError::Timeout, e.message
46
+ else
47
+ store_whiplash_error!(:connection, options)
48
+ Rails.logger.error "[Whiplash] Request to #{url} failed"
49
+ raise ProviderError::InternalServerError, e.message
50
+ end
51
+ end
52
+ return response.body if response.success?
53
+ message = response.body if response.body.is_a? String
54
+ message = response.body.dig('error') if response.body.respond_to?(:dig)
55
+ store_whiplash_error!(response.status)
56
+ error_response(response.status, 'Whiplash', message)
18
57
  end
19
58
 
20
59
  def delete(endpoint, params = {}, headers = nil)
@@ -45,6 +84,34 @@ module Whiplash
45
84
  headers: headers)
46
85
  end
47
86
 
87
+ def delete!(endpoint, params = {}, headers = nil)
88
+ app_request!(method: :delete,
89
+ endpoint: endpoint,
90
+ params: params,
91
+ headers: headers)
92
+ end
93
+
94
+ def get!(endpoint, params = {}, headers = nil)
95
+ app_request!(method: :get,
96
+ endpoint: endpoint,
97
+ params: params,
98
+ headers: headers)
99
+ end
100
+
101
+ def post!(endpoint, params = {}, headers = nil)
102
+ app_request!(method: :post,
103
+ endpoint: endpoint,
104
+ params: params,
105
+ headers: headers)
106
+ end
107
+
108
+ def put!(endpoint, params = {}, headers = nil)
109
+ app_request!(method: :put,
110
+ endpoint: endpoint,
111
+ params: params,
112
+ headers: headers)
113
+ end
114
+
48
115
  def sanitize_headers(headers)
49
116
  if headers
50
117
  {}.tap do |hash|
@@ -55,6 +122,36 @@ module Whiplash
55
122
  end
56
123
  end
57
124
 
125
+ def store_whiplash_error!(error, options={})
126
+ return unless defined?(Appsignal)
127
+ options = options.with_indifferent_access
128
+ Appsignal.increment_counter(
129
+ "whiplash_error",
130
+ 1.0,
131
+ shop_id: options[:shop_id],
132
+ customer_id: options[:customer_id],
133
+ error: error.to_s
134
+ )
135
+ end
136
+
137
+ def error_codes
138
+ WhiplashApiError.codes
139
+ end
140
+
141
+ def select_error(status_code)
142
+ unless error_codes.keys.include? status_code
143
+ Rails.logger.info "[Provider] Unknown status code from #{self.class.name}: #{status_code}"
144
+ return WhiplashApiError::UnknownError
145
+ end
146
+ error_codes[status_code]
147
+ end
148
+
149
+ # Select an applicable error message on a request to a provider.
150
+ def error_response(status_code, message=nil)
151
+ message ||= "Your request has been denied as a #{status_code} error"
152
+ raise select_error(status_code), message
153
+ end
154
+
58
155
  end
59
156
  end
60
157
  end
@@ -1,5 +1,5 @@
1
1
  module Whiplash
2
2
  class App
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whiplash-app
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Don Sullivan, Mark Dickson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-12 00:00:00.000000000 Z
11
+ date: 2019-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2
@@ -110,6 +110,7 @@ files:
110
110
  - Rakefile
111
111
  - bin/console
112
112
  - bin/setup
113
+ - lib/errors/whiplash_api_error.rb
113
114
  - lib/whiplash/app.rb
114
115
  - lib/whiplash/app/api_config.rb
115
116
  - lib/whiplash/app/caching.rb
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  version: '0'
139
140
  requirements: []
140
141
  rubyforge_project:
141
- rubygems_version: 2.6.11
142
+ rubygems_version: 2.7.6.2
142
143
  signing_key:
143
144
  specification_version: 4
144
145
  summary: this gem provides connectivity to the Whiplash API for authentication and