eligible 1.0 → 3.0.0.beta17

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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +76 -0
  3. data/.codeclimate.yml +23 -0
  4. data/.gitignore +3 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +1158 -0
  7. data/.ruby-version +1 -0
  8. data/CHANGELOG.md +170 -0
  9. data/Gemfile +4 -0
  10. data/Gemfile.lock +66 -0
  11. data/LICENSE +1 -1
  12. data/README.md +700 -93
  13. data/Rakefile +12 -2
  14. data/eligible.gemspec +14 -16
  15. data/lib/eligible/api_resource.rb +49 -5
  16. data/lib/eligible/calculator_deploy_url.rb +7 -0
  17. data/lib/eligible/claim.rb +22 -6
  18. data/lib/eligible/coverage.rb +19 -0
  19. data/lib/eligible/coverage_resource.rb +23 -0
  20. data/lib/eligible/customer.rb +19 -0
  21. data/lib/eligible/demographic.rb +6 -35
  22. data/lib/eligible/eligible_object.rb +12 -15
  23. data/lib/eligible/encryptor.rb +121 -0
  24. data/lib/eligible/enrollment.rb +23 -0
  25. data/lib/eligible/errors/eligible_error.rb +6 -3
  26. data/lib/eligible/errors/invalid_request_error.rb +4 -0
  27. data/lib/eligible/icd.rb +16 -0
  28. data/lib/eligible/json.rb +5 -15
  29. data/lib/eligible/lockbox.rb +39 -0
  30. data/lib/eligible/medicare.rb +11 -0
  31. data/lib/eligible/oauth_token.rb +9 -0
  32. data/lib/eligible/ocr.rb +15 -0
  33. data/lib/eligible/original_signature_pdf.rb +45 -0
  34. data/lib/eligible/payer.rb +17 -0
  35. data/lib/eligible/payer_mapping.rb +37 -0
  36. data/lib/eligible/payment.rb +11 -0
  37. data/lib/eligible/preauth_resource.rb +11 -0
  38. data/lib/eligible/precert.rb +15 -0
  39. data/lib/eligible/provider_model.rb +7 -0
  40. data/lib/eligible/public_key.rb +27 -0
  41. data/lib/eligible/received_pdf.rb +26 -0
  42. data/lib/eligible/referral.rb +11 -0
  43. data/lib/eligible/risk_assessment.rb +15 -0
  44. data/lib/eligible/session_token.rb +11 -0
  45. data/lib/eligible/ticket.rb +40 -0
  46. data/lib/eligible/util.rb +29 -38
  47. data/lib/eligible/v1_0/action.rb +9 -0
  48. data/lib/eligible/v1_0/attribute.rb +9 -0
  49. data/lib/eligible/v1_0/charge.rb +13 -0
  50. data/lib/eligible/v1_0/claim.rb +25 -0
  51. data/lib/eligible/v1_0/claim_service_line.rb +9 -0
  52. data/lib/eligible/v1_0/contract.rb +9 -0
  53. data/lib/eligible/v1_0/device.rb +9 -0
  54. data/lib/eligible/v1_0/discount.rb +9 -0
  55. data/lib/eligible/v1_0/enrollment.rb +17 -0
  56. data/lib/eligible/v1_0/estimate.rb +29 -0
  57. data/lib/eligible/v1_0/estimate_service_line.rb +17 -0
  58. data/lib/eligible/v1_0/fee.rb +21 -0
  59. data/lib/eligible/v1_0/fee_refund.rb +29 -0
  60. data/lib/eligible/v1_0/file.rb +17 -0
  61. data/lib/eligible/v1_0/file_link.rb +13 -0
  62. data/lib/eligible/v1_0/insurance_company.rb +21 -0
  63. data/lib/eligible/v1_0/insurance_company_alias.rb +9 -0
  64. data/lib/eligible/v1_0/insurance_policy.rb +9 -0
  65. data/lib/eligible/v1_0/patient_question.rb +9 -0
  66. data/lib/eligible/v1_0/patient_questionnaire.rb +9 -0
  67. data/lib/eligible/v1_0/patient_record.rb +9 -0
  68. data/lib/eligible/v1_0/patient_statement.rb +54 -0
  69. data/lib/eligible/v1_0/patient_statement_service_line.rb +13 -0
  70. data/lib/eligible/v1_0/payment_report.rb +21 -0
  71. data/lib/eligible/v1_0/product.rb +9 -0
  72. data/lib/eligible/v1_0/provider.rb +9 -0
  73. data/lib/eligible/v1_0/remark.rb +21 -0
  74. data/lib/eligible/v1_0/reports/accuracy_stats.rb +23 -0
  75. data/lib/eligible/v1_0/reports/estimate_friction.rb +23 -0
  76. data/lib/eligible/v1_0/reports/in_scope_distribution.rb +23 -0
  77. data/lib/eligible/v1_0/rest_api_base.rb +44 -0
  78. data/lib/eligible/v1_0/rule.rb +13 -0
  79. data/lib/eligible/v1_0/session.rb +21 -0
  80. data/lib/eligible/v1_0/transaction.rb +21 -0
  81. data/lib/eligible/v1_0/treatment.rb +9 -0
  82. data/lib/eligible/v1_0/value_list.rb +9 -0
  83. data/lib/eligible/v1_0/value_list_item.rb +9 -0
  84. data/lib/eligible/v1_0/verification.rb +17 -0
  85. data/lib/eligible/version.rb +1 -1
  86. data/lib/eligible/visit_type.rb +11 -0
  87. data/lib/eligible/x12.rb +8 -0
  88. data/lib/eligible.rb +320 -110
  89. metadata +148 -67
  90. data/CONTRIBUTORS +0 -1
  91. data/lib/eligible/plan.rb +0 -42
  92. data/lib/eligible/service.rb +0 -39
  93. data/test/test_eligible.rb +0 -279
  94. data/test/test_helper.rb +0 -67
data/lib/eligible.rb CHANGED
@@ -2,34 +2,123 @@ require 'cgi'
2
2
  require 'set'
3
3
  require 'rubygems'
4
4
  require 'openssl'
5
+ require 'net/https'
5
6
 
6
- gem 'rest-client', '~> 1.4'
7
7
  require 'rest_client'
8
8
  require 'multi_json'
9
9
 
10
10
  require 'eligible/version'
11
+ require 'eligible/encryptor'
11
12
  require 'eligible/util'
12
13
  require 'eligible/json'
13
14
  require 'eligible/eligible_object'
14
15
  require 'eligible/api_resource'
15
- require 'eligible/plan'
16
- require 'eligible/service'
16
+ require 'eligible/coverage_resource'
17
17
  require 'eligible/demographic'
18
18
  require 'eligible/claim'
19
+ require 'eligible/enrollment'
20
+ require 'eligible/coverage'
21
+ require 'eligible/payment'
22
+ require 'eligible/x12'
23
+ require 'eligible/medicare'
24
+ require 'eligible/ticket'
25
+ require 'eligible/customer'
26
+ require 'eligible/ocr'
27
+ require 'eligible/original_signature_pdf'
28
+ require 'eligible/oauth_token'
29
+ require 'eligible/received_pdf'
30
+ require 'eligible/payer'
31
+ require 'eligible/payer_mapping'
32
+ require 'eligible/preauth_resource'
33
+ require 'eligible/precert'
34
+ require 'eligible/referral'
35
+ require 'eligible/public_key'
36
+ require 'eligible/lockbox'
37
+ require 'eligible/session_token'
38
+ require 'eligible/visit_type'
39
+ require 'eligible/provider_model'
40
+ require 'eligible/calculator_deploy_url'
41
+ require 'eligible/risk_assessment'
42
+ require 'eligible/icd'
43
+
44
+ # New REST API Endpoints
45
+ require 'eligible/v1_0/rest_api_base'
46
+ require 'eligible/v1_0/action'
47
+ require 'eligible/v1_0/attribute'
48
+ require 'eligible/v1_0/charge'
49
+ require 'eligible/v1_0/claim'
50
+ require 'eligible/v1_0/claim_service_line'
51
+ require 'eligible/v1_0/contract'
52
+ require 'eligible/v1_0/device'
53
+ require 'eligible/v1_0/discount'
54
+ require 'eligible/v1_0/enrollment'
55
+ require 'eligible/v1_0/estimate'
56
+ require 'eligible/v1_0/estimate_service_line'
57
+ require 'eligible/v1_0/fee'
58
+ require 'eligible/v1_0/fee_refund'
59
+ require 'eligible/v1_0/file'
60
+ require 'eligible/v1_0/file_link'
61
+ require 'eligible/v1_0/insurance_company'
62
+ require 'eligible/v1_0/insurance_company_alias'
63
+ require 'eligible/v1_0/insurance_policy'
64
+ require 'eligible/v1_0/patient_record'
65
+ require 'eligible/v1_0/patient_statement'
66
+ require 'eligible/v1_0/patient_statement_service_line'
67
+ require 'eligible/v1_0/payment_report'
68
+ require 'eligible/v1_0/patient_question'
69
+ require 'eligible/v1_0/patient_questionnaire'
70
+ require 'eligible/v1_0/product'
71
+ require 'eligible/v1_0/provider'
72
+ require 'eligible/v1_0/remark'
73
+ require 'eligible/v1_0/rule'
74
+ require 'eligible/v1_0/session'
75
+ require 'eligible/v1_0/transaction'
76
+ require 'eligible/v1_0/treatment'
77
+ require 'eligible/v1_0/value_list'
78
+ require 'eligible/v1_0/value_list_item'
79
+ require 'eligible/v1_0/verification'
80
+ require 'eligible/v1_0/reports/accuracy_stats'
81
+ require 'eligible/v1_0/reports/estimate_friction'
82
+ require 'eligible/v1_0/reports/in_scope_distribution'
19
83
 
20
84
  # Errors
21
85
  require 'eligible/errors/eligible_error'
22
86
  require 'eligible/errors/api_connection_error'
23
87
  require 'eligible/errors/authentication_error'
24
88
  require 'eligible/errors/api_error'
89
+ require 'eligible/errors/invalid_request_error'
25
90
 
26
91
  module Eligible
27
- @@api_key = nil
28
- @@api_base = "https://v1.eligibleapi.net"
29
- @@api_version = 1
92
+ @@api_key = nil
93
+ @@test = false
94
+ @@api_version = '1.5'
95
+ @@api_base = "https://gds.eligibleapi.com/v#{@@api_version}"
96
+ @@fingerprints = %w(a1cd762a9f4be0f3b6bdd6300e52c6ce8d7d67f5
97
+ 36d6b6f98a2b9bcdf4321d1978553e23cf044b53
98
+ d93b7697100fe978ae0f78fbf2a2443cc1958ca3
99
+ 896ce24f7a83eb656c040985fdb50ce39f90b813)
100
+ @@eligible_account = nil
101
+ @@eligible_account_id = nil
102
+
103
+ def self.api_url(url = '', rest_api_version = nil)
104
+ api_base = rest_api_version ? @@api_base.gsub(/v(\d).(\d)/, "v#{rest_api_version}") : @@api_base
105
+ api_base + url.to_s
106
+ end
107
+
108
+ def self.eligible_account
109
+ @@eligible_account
110
+ end
111
+
112
+ def self.eligible_account_id
113
+ @@eligible_account_id
114
+ end
30
115
 
31
- def self.api_url(url='')
32
- @@api_base + url
116
+ def self.eligible_account=(eligible_account)
117
+ @@eligible_account = eligible_account
118
+ end
119
+
120
+ def self.eligible_account_id=(eligible_account_id)
121
+ @@eligible_account_id = eligible_account_id
33
122
  end
34
123
 
35
124
  def self.api_key
@@ -40,161 +129,284 @@ module Eligible
40
129
  @@api_key = api_key
41
130
  end
42
131
 
132
+ def self.api_base
133
+ @@api_base
134
+ end
135
+
136
+ def self.api_base=(api_base)
137
+ @@api_base = api_base
138
+ end
139
+
140
+ def self.test
141
+ @@test ? 'true' : 'false'
142
+ end
143
+
144
+ def self.test=(is_test)
145
+ @@test = is_test
146
+ end
147
+
43
148
  def self.api_version=(version)
44
149
  @@api_version = version
45
150
  end
46
151
 
47
152
  def self.api_version
48
153
  @@api_version
49
- end
50
-
51
- def self.request(method, url, api_key, params={}, headers={})
52
- api_key ||= @@api_key
53
- raise AuthenticationError.new('No API key provided. (HINT: set your API key using "Eligible.api_key = <API-KEY>".') unless api_key
54
-
55
- # if !verify_ssl_certs
56
- # unless @no_verify
57
- # $stderr.puts "WARNING: Running without SSL cert verification. Execute 'Eligible.verify_ssl_certs = true' to enable verification."
58
- # @no_verify = true
59
- # end
60
- # ssl_opts = { :verify_ssl => false }
61
- # elsif !Util.file_readable(@@ssl_bundle_path)
62
- # unless @no_bundle
63
- # $stderr.puts "WARNING: Running without SSL cert verification because #{@@ssl_bundle_path} isn't readable"
64
- # @no_bundle = true
65
- # end
66
- # ssl_opts = { :verify_ssl => false }
67
- # else
68
- # ssl_opts = {
69
- # :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
70
- # :ssl_ca_file => @@ssl_bundle_path
71
- # }
72
- # end
73
- uname = (@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil)
74
- lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
75
- ua = {
76
- :bindings_version => Eligible::VERSION,
77
- :lang => 'ruby',
78
- :lang_version => lang_version,
79
- :platform => RUBY_PLATFORM,
80
- :publisher => 'eligible',
81
- :uname => uname
82
- }
154
+ end
83
155
 
84
- # params = Util.objects_to_ids(params)
85
- url = self.api_url(url)
86
- case method.to_s.downcase.to_sym
87
- when :get, :head, :delete
88
- # Make params into GET parameters
89
- url += "?api_key=#{api_key}"
90
- if params && params.count > 0
91
- query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
92
- url += "&#{query_string}"
93
- end
94
- payload = nil
95
- else
96
- payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
97
- end
156
+ def self.fingerprints
157
+ @@fingerprints
158
+ end
98
159
 
99
- begin
100
- headers = { :x_eligible_client_user_agent => Eligible::JSON.dump(ua) }.merge(headers)
101
- rescue => e
102
- headers = {
103
- :x_eligible_client_raw_user_agent => ua.inspect,
104
- :error => "#{e} (#{e.class})"
105
- }.merge(headers)
106
- end
160
+ def self.add_fingerprint(digest)
161
+ $stderr.puts 'The embedded certificate fingerprint was modified. This should only be done if instructed to by eligible support staff'
162
+ @@fingerprints << digest
163
+ end
107
164
 
108
- headers = {
109
- :user_agent => "Eligible/v1 RubyBindings/#{Eligible::VERSION}",
110
- :authorization => "Bearer #{api_key}",
111
- :content_type => 'application/x-www-form-urlencoded'
112
- }.merge(headers)
165
+ def self.direct_response?(params)
166
+ params[:format].is_a?(String) && params[:format].downcase == 'x12'
167
+ end
113
168
 
114
- if self.api_version
115
- headers[:eligible_version] = self.api_version
116
- end
169
+ def self.test_key?(params)
170
+ Util.key?(params, :test)
171
+ end
172
+
173
+ def self.api_key?(params)
174
+ Util.key?(params, :api_key)
175
+ end
176
+
177
+ def self.rest_api_version?(params)
178
+ Util.key?(params, :rest_api_version)
179
+ end
180
+
181
+ def self.request(method, url, api_key, params = {}, headers = {})
182
+ session_token = Util.value(params, :session_token)
183
+ api_key ||= @@api_key unless session_token
184
+ test = self.test
185
+ api_key = Util.value(params, :api_key) if api_key?(params)
186
+ test = Util.value(params, :test) if test_key?(params)
187
+ rest_api_version = Util.value(params, :rest_api_version) if rest_api_version?(params)
188
+ basic_auth = true if rest_api_version?(params)
189
+
190
+ fail AuthenticationError, 'No API key provided. (HINT: set your API key using "Eligible.api_key = <API-KEY>".' unless api_key || session_token
191
+
192
+ lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
193
+ debug_info = {
194
+ bindings_version: Eligible::VERSION,
195
+ lang: 'ruby',
196
+ lang_version: lang_version,
197
+ platform: RUBY_PLATFORM,
198
+ publisher: 'eligible',
199
+ uname: uname
200
+ }
201
+
202
+ # Set request URL and Payload based on new and old endpoints version
203
+ url, payload = generate_request_url_and_payload(
204
+ method, url, params, { test: test, rest_api_version: rest_api_version, api_key: api_key, basic_auth: basic_auth },
205
+ )
206
+
207
+ # Set request Headers and Authorization based on new and old endpoints version
208
+ headers = generate_request_headers(headers, debug_info, basic_auth, { api_key: api_key, session_token: session_token })
117
209
 
118
210
  opts = {
119
- :method => method,
120
- :url => url,
121
- :headers => headers,
122
- :open_timeout => 30,
123
- :payload => payload,
124
- :timeout => 80
125
- }#.merge(ssl_opts)
126
-
211
+ method: method,
212
+ url: url,
213
+ headers: headers,
214
+ open_timeout: 30,
215
+ payload: payload,
216
+ timeout: 80,
217
+ ssl_verify_callback: verify_certificate,
218
+ ssl_verify_callback_warnings: false
219
+ }
220
+
127
221
  begin
128
222
  response = execute_request(opts)
223
+
129
224
  rescue SocketError => e
130
- self.handle_restclient_error(e)
225
+ handle_restclient_error(e)
226
+
131
227
  rescue NoMethodError => e
132
228
  # Work around RestClient bug
133
- if e.message =~ /\WRequestFailed\W/
134
- e = APIConnectionError.new('Unexpected HTTP response code')
135
- self.handle_restclient_error(e)
136
- else
137
- raise
138
- end
229
+ raise unless e.message =~ /\WRequestFailed\W/
230
+
231
+ e = APIConnectionError.new('Unexpected HTTP response code')
232
+ handle_restclient_error(e)
233
+
139
234
  rescue RestClient::ExceptionWithResponse => e
140
- if rcode = e.http_code and rbody = e.http_body
141
- self.handle_api_error(rcode, rbody)
235
+ err_rcode = e.http_code
236
+ err_rbody = e.http_body
237
+
238
+ if err_rcode && err_rbody
239
+ handle_api_error(err_rcode, err_rbody)
142
240
  else
143
- self.handle_restclient_error(e)
241
+ handle_restclient_error(e)
144
242
  end
243
+
145
244
  rescue RestClient::Exception, Errno::ECONNREFUSED => e
146
- self.handle_restclient_error(e)
245
+ handle_restclient_error(e)
147
246
  end
148
247
 
149
248
  rbody = response.body
150
249
  rcode = response.code
250
+
151
251
  begin
152
252
  # Would use :symbolize_names => true, but apparently there is
153
253
  # some library out there that makes symbolize_names not work.
154
- resp = Eligible::JSON.load(rbody)
254
+ resp = direct_response?(params) ? rbody : Eligible::JSON.load(rbody)
155
255
  rescue MultiJson::DecodeError
156
256
  raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
157
257
  end
158
258
 
159
259
  resp = Util.symbolize_names(resp)
160
- [resp, api_key]
260
+ return [ resp, api_key ]
261
+ end
262
+
263
+ def self.generate_request_url_and_payload(method, url, params, options)
264
+ # GET requests, parameters on the query string
265
+ # POST requests, parameters as json in the body
266
+ url = api_url(url, options[:rest_api_version])
267
+ # Used rest_api_version param only to identify new REST API version, and is not required to make calls for new REST api endpoints
268
+ params.delete(:rest_api_version)
269
+ case method.to_s.downcase.to_sym
270
+ when :get, :head, :delete
271
+ url = fetch_url_with_query_string(params, url, options)
272
+ payload = nil
273
+ else
274
+ payload = request_payload(options, params)
275
+ end
276
+
277
+ [url, payload]
278
+ end
279
+
280
+ def self.fetch_url_with_query_string(params, url, options)
281
+ url += options_query_string(options)
282
+ return url unless params || params.count == 0
283
+
284
+ query_string = params_query_string(params)
285
+ url += options[:basic_auth] ? "?#{query_string}" : "&#{query_string}"
286
+ url
287
+ end
288
+
289
+ def self.options_query_string(options)
290
+ options[:basic_auth] ? '' : "?test=#{options[:test]}&api_key=#{options[:api_key]}"
291
+ end
292
+
293
+ def self.params_query_string(params)
294
+ Util.flatten_params(params).collect { |key, value| "#{key}=#{Util.url_encode(value)}" }.join('&')
295
+ end
296
+
297
+ def self.request_payload(options, params)
298
+ params.merge!('test' => options[:test], 'api_key' => options[:api_key]) unless options[:basic_auth]
299
+ Util.key?(params, :file) ? params : Eligible::JSON.dump(params)
300
+ end
301
+
302
+ def self.generate_request_headers(headers, debug_info, basic_auth, auth_options)
303
+ begin
304
+ headers = { x_eligible_debuginfo: Eligible::JSON.dump(debug_info) }.merge(headers)
305
+ rescue => e
306
+ headers = {
307
+ x_eligible_client_raw_user_agent: debug_info.inspect,
308
+ error: "#{e} (#{e.class})"
309
+ }.merge(headers)
310
+ end
311
+
312
+ headers = {
313
+ user_agent: "eligible-ruby/#{Eligible::VERSION}",
314
+ content_type: 'application/json'
315
+ }.merge(headers)
316
+
317
+ headers[:authorization] = authorization_header(basic_auth, auth_options)
318
+ headers[:eligible_version] = api_version if api_version
319
+ headers[:eligible_account] = eligible_account if eligible_account
320
+ headers[:eligible_account_id] = eligible_account_id if eligible_account_id
321
+ headers
322
+ end
323
+
324
+ def self.authorization_header(basic_auth, auth_options)
325
+ # Using Bearer scheme for Session Token Auth for new REST API endpoints (v1.0)
326
+ return "Bearer #{auth_options[:session_token]}" if basic_auth && auth_options[:session_token]
327
+
328
+ # Using Basic Auth for new REST API endpoints (v1.0)
329
+ basic_auth_token = Base64.strict_encode64("#{auth_options[:api_key]}:")
330
+ "Basic #{basic_auth_token}" if basic_auth
331
+ end
332
+
333
+ def self.verify_certificate
334
+ lambda do |preverify_ok, certificate_store|
335
+ return true if test == 'true'
336
+ return false unless preverify_ok
337
+ received = certificate_store.chain.first
338
+ return true unless received.to_der == certificate_store.current_cert.to_der
339
+ valid_fingerprint?(received)
340
+ end
341
+ end
342
+
343
+ def self.valid_fingerprint?(received)
344
+ fingerprints.include?(OpenSSL::Digest::SHA1.hexdigest(received.to_der))
161
345
  end
162
346
 
163
347
  private
164
348
 
349
+ def self.uname
350
+ @@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil
351
+ end
352
+
165
353
  def self.execute_request(opts)
166
354
  RestClient::Request.execute(opts)
167
355
  end
168
356
 
357
+ def self.error_message(error, errors)
358
+ message = compose_message_from_errors(errors)
359
+ return message if message
360
+
361
+ return compose_message_from_error(error)
362
+ end
363
+
364
+ def self.compose_message_from_errors(errors)
365
+ return unless errors.is_a?(Array)
366
+
367
+ return errors.first[:message] if errors.size == 1
368
+ return errors.each_with_index.map { |error, index| "#{index + 1}. #{error[:message]}" }.join("\n")
369
+ end
370
+
371
+ def self.compose_message_from_error(error)
372
+ return error.to_s unless error.is_a?(Hash)
373
+ result = error[:details] || error[:reject_reason_description] || error
374
+ return result.to_s
375
+ end
376
+
169
377
  def self.handle_api_error(rcode, rbody)
170
378
  begin
171
- error_obj = Eligible::JSON.load(rbody)
172
- error_obj = Util.symbolize_names(error_obj)
173
- error = error_obj[:error] or raise EligibleError.new # escape from parsing
379
+ error_obj = Util.symbolize_names(Eligible::JSON.load(rbody))
380
+ fail EligibleError unless error_obj.keys.any? { |k| [:error, :errors].include? k }
381
+ error = error_obj[:error]
382
+ errors = error_obj[:errors]
383
+
174
384
  rescue MultiJson::DecodeError, EligibleError
175
385
  raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
176
386
  end
177
387
 
388
+ error_msg = error_message(error, errors)
389
+
178
390
  case rcode
179
391
  when 400, 404 then
180
- raise invalid_request_error(error, rcode, rbody, error_obj)
392
+ raise invalid_request_error(error_msg, rcode, rbody, error_obj)
181
393
  when 401
182
- raise authentication_error(error, rcode, rbody, error_obj)
394
+ raise authentication_error(error_msg, rcode, rbody, error_obj)
183
395
  else
184
- raise api_error(error, rcode, rbody, error_obj)
396
+ raise api_error(error_msg, rcode, rbody, error_obj)
185
397
  end
186
398
  end
187
399
 
188
- def self.invalid_request_error(error, rcode, rbody, error_obj)
189
- InvalidRequestError.new(error[0][:message], error[:param], rcode, rbody, error_obj)
400
+ def self.invalid_request_error(error_msg, rcode, rbody, error_obj)
401
+ InvalidRequestError.new(error_msg, rcode, rbody, error_obj)
190
402
  end
191
403
 
192
- def self.authentication_error(error, rcode, rbody, error_obj)
193
- AuthenticationError.new(error[0][:message], rcode, rbody, error_obj)
404
+ def self.authentication_error(error_msg, rcode, rbody, error_obj)
405
+ AuthenticationError.new(error_msg, rcode, rbody, error_obj)
194
406
  end
195
407
 
196
- def self.api_error(error, rcode, rbody, error_obj)
197
- APIError.new(error[0][:message], rcode, rbody, error_obj)
408
+ def self.api_error(error_msg, rcode, rbody, error_obj)
409
+ APIError.new(error_msg, rcode, rbody, error_obj)
198
410
  end
199
411
 
200
412
  def self.handle_restclient_error(e)
@@ -204,12 +416,10 @@ module Eligible
204
416
  when RestClient::SSLCertificateNotVerified
205
417
  message = "Could not verify Eligible's SSL certificate."
206
418
  when SocketError
207
- message = "Unexpected error communicating when trying to connect to Eligible."
419
+ message = 'Unexpected error communicating when trying to connect to Eligible.'
208
420
  else
209
- message = "Unexpected error communicating with Eligible. If this problem persists, let us know at support@eligible.com."
421
+ message = 'Unexpected error communicating with Eligible. If this problem persists, let us know at support@eligible.com.'
210
422
  end
211
- message += "\n\n(Network error: #{e.message})"
212
- raise APIConnectionError.new(message)
423
+ fail APIConnectionError, "#{message}\n\n(Network error: #{e.message})"
213
424
  end
214
-
215
425
  end