ncore 2.1.2 → 3.1.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 +4 -4
- data/CHANGELOG.md +54 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/example/lib/my_api/api_config.rb +8 -0
- data/example/lib/my_api/rails/railtie.rb +4 -0
- data/lib/ncore.rb +32 -3
- data/lib/ncore/associations.rb +13 -13
- data/lib/ncore/attributes.rb +40 -17
- data/lib/ncore/base.rb +6 -3
- data/lib/ncore/client.rb +28 -26
- data/lib/ncore/client_cache.rb +48 -0
- data/lib/ncore/configuration.rb +15 -2
- data/lib/ncore/exceptions.rb +7 -1
- data/lib/ncore/identity.rb +27 -0
- data/lib/ncore/lifecycle.rb +3 -3
- data/lib/ncore/methods/all.rb +3 -7
- data/lib/ncore/methods/build.rb +2 -2
- data/lib/ncore/methods/count.rb +1 -1
- data/lib/ncore/methods/create.rb +4 -5
- data/lib/ncore/methods/delete.rb +6 -7
- data/lib/ncore/methods/delete_bulk.rb +4 -4
- data/lib/ncore/methods/delete_single.rb +4 -5
- data/lib/ncore/methods/find.rb +5 -6
- data/lib/ncore/methods/find_single.rb +5 -9
- data/lib/ncore/methods/update.rb +6 -7
- data/lib/ncore/methods/update_bulk.rb +26 -0
- data/lib/ncore/rails/active_model.rb +24 -14
- data/lib/ncore/rails/module_fix.rb +19 -0
- data/lib/ncore/singleton_base.rb +4 -3
- data/lib/ncore/ssl/ca-certificates.crt +2382 -3122
- data/lib/ncore/util.rb +10 -2
- data/lib/ncore/version.rb +1 -1
- data/ncore.gemspec +1 -1
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dc98407fe99f0886bc4462862fa5141d91be2a92ce6e00845e3770d9d10ffa4
|
4
|
+
data.tar.gz: 756f94ca80ffed714f51ba6822bb30b27e34a270e7bffd1e33c3ac84d2b4d011
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54c04edbf55eaeb2a4100e4dd6fdaf0ce4a4485aa6c0d144bf09f4284bd926cb257e0e1ae9b04a93ead527173a7b5a7f263a36159f7013af5fa8a05dc5032ae6
|
7
|
+
data.tar.gz: ae8e883bb03b9d1d1c18874e69c4719f9ab9420a448f347bd4203ffbce31996fe7a94e0f31714e505cbd06d52177af5a450b36825b23aa79a3bffe15ce053a28
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
#### 3.1.0
|
2
|
+
|
3
|
+
- Add .bulk_update and bulk_update!
|
4
|
+
|
5
|
+
#### 3.0.0
|
6
|
+
|
7
|
+
BREAKING CHANGES
|
8
|
+
- Update has_many, belongs_to signatures
|
9
|
+
- Rename Base#url -> #resource_path
|
10
|
+
- Drop ActiveModel <= 4.1
|
11
|
+
- `#errors` is now always an ActiveModel::Errors instance
|
12
|
+
|
13
|
+
DEPRECATION NOTICE
|
14
|
+
- ValidationError is deprecated and will be removed in 3.1.
|
15
|
+
|
16
|
+
Other changes
|
17
|
+
- Add :cache option for requests
|
18
|
+
Set default store at MyApi::Api.cache_store=
|
19
|
+
See example railtie.rb for auto-config
|
20
|
+
Examples:
|
21
|
+
SomeResource.all(cache: true)
|
22
|
+
uses MyApi::Api.cache_store
|
23
|
+
SomeResource.find(id, cache: {expires_in: 5.minutes})
|
24
|
+
uses MyApi::Api.cache_store with specified options
|
25
|
+
SomeResource.find(id, cache: Dalli::Store.new(...))
|
26
|
+
uses provided cache store (with its default options)
|
27
|
+
- Make bearer_credential_key allow strings or symbols
|
28
|
+
- Warn on attr name collision
|
29
|
+
- Update CA certificates
|
30
|
+
- Better default output for #as_json
|
31
|
+
- Allow ActiveModel/Support 6.0
|
32
|
+
- Resolve deprecation messages on Ruby 2.6
|
33
|
+
- Add #factory
|
34
|
+
- API response :errors may be hash or array
|
35
|
+
- Add RecordInvalid#errors
|
36
|
+
- Better Ruby and ActiveModel integration
|
37
|
+
- #eql?, #==, #hash
|
38
|
+
- #model_name
|
39
|
+
- #i18n_scope, config via Api.i18n_scope=
|
40
|
+
- #cache_key, #cache_version, #cache_key_with_version
|
41
|
+
|
42
|
+
#### 2.2.2
|
43
|
+
|
44
|
+
- Update certs
|
45
|
+
|
46
|
+
#### 2.2.1
|
47
|
+
|
48
|
+
- Fix decimal attributes on Ruby <= 2.5.x
|
49
|
+
|
50
|
+
#### 2.2.0
|
51
|
+
|
52
|
+
- Allow ActiveSupport 6.0
|
53
|
+
- Resolve deprecation messages on Ruby 2.6
|
54
|
+
|
1
55
|
#### 2.1.2
|
2
56
|
|
3
57
|
- Fix URL processing when frozen
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
NCore is a Ruby gem designed to help build REST API clients. It is not an API
|
4
4
|
client by itself, but provides several useful building blocks to build one.
|
5
5
|
|
6
|
-
It relies on `excon` for HTTP handling and `
|
6
|
+
It relies on `excon` for HTTP handling and `activemodel`.
|
7
7
|
|
8
8
|
If present, uses `multi_json`. Otherwise, the stdlib 'json' is used.
|
9
9
|
'multi_json' with an accelerated json gem is recommended.
|
@@ -21,6 +21,8 @@ module MyApi
|
|
21
21
|
|
22
22
|
self.strict_attributes = false
|
23
23
|
|
24
|
+
self.i18n_scope = :my_api
|
25
|
+
|
24
26
|
self.instrument_key = 'request.my_api'
|
25
27
|
|
26
28
|
self.status_page = 'http://my.api.status.page'
|
@@ -30,6 +32,12 @@ module MyApi
|
|
30
32
|
# self.bearer_credential_key = :api_key
|
31
33
|
|
32
34
|
self.credentials_error_message = %Q{Missing API credentials. Set default credentials using "MyApi.credentials = {api_user: YOUR_API_USER, api_key: YOUR_API_KEY}"}
|
35
|
+
|
36
|
+
# self.verify_ssl = true
|
37
|
+
|
38
|
+
# self.ssl_cert_bundle = 'path/to/bundle.crt'
|
39
|
+
|
40
|
+
# self.logger = Logger.new(STDOUT)
|
33
41
|
end
|
34
42
|
|
35
43
|
end
|
data/lib/ncore.rb
CHANGED
@@ -1,14 +1,43 @@
|
|
1
1
|
require 'active_support/all'
|
2
|
+
require 'active_model'
|
2
3
|
require 'excon'
|
3
4
|
require 'pp'
|
4
5
|
|
5
|
-
%w(
|
6
|
+
%w(
|
7
|
+
version
|
8
|
+
builder
|
9
|
+
configuration
|
10
|
+
associations
|
11
|
+
attributes
|
12
|
+
client
|
13
|
+
client_cache
|
14
|
+
collection
|
15
|
+
exceptions
|
16
|
+
identity
|
17
|
+
lifecycle
|
18
|
+
util
|
19
|
+
base
|
20
|
+
singleton_base
|
21
|
+
).each do |f|
|
6
22
|
require "ncore/#{f}"
|
7
23
|
end
|
8
24
|
|
9
|
-
%w(
|
25
|
+
%w(
|
26
|
+
all
|
27
|
+
build
|
28
|
+
count
|
29
|
+
create
|
30
|
+
delete
|
31
|
+
delete_bulk
|
32
|
+
delete_single
|
33
|
+
find
|
34
|
+
find_single
|
35
|
+
update
|
36
|
+
update_bulk
|
37
|
+
).each do |f|
|
10
38
|
require "ncore/methods/#{f}"
|
11
39
|
end
|
12
40
|
|
13
41
|
require 'ncore/rails/action_controller' if defined?(::ActionController)
|
14
|
-
require 'ncore/rails/active_model'
|
42
|
+
require 'ncore/rails/active_model'
|
43
|
+
require 'ncore/rails/module_fix'
|
data/lib/ncore/associations.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module NCore
|
2
2
|
module Associations
|
3
3
|
|
4
|
-
def has_many(assoc,
|
4
|
+
def has_many(assoc, class_name: nil)
|
5
5
|
assoc = assoc.to_s
|
6
|
-
klass
|
6
|
+
klass = class_name || "#{module_name}::#{assoc.camelize.singularize}"
|
7
7
|
key = "#{attrib_name}_id"
|
8
8
|
class_eval <<-M1, __FILE__, __LINE__+1
|
9
9
|
def #{assoc}(params={})
|
10
10
|
return [] unless id
|
11
11
|
reload = params.delete :reload
|
12
|
-
params = parse_request_params(params).reverse_merge credentials: api_creds
|
13
12
|
cacheable = params.except(:credentials, :request).empty?
|
14
|
-
params.
|
13
|
+
params = parse_request_params(params).reverse_merge credentials: api_creds
|
14
|
+
params[:#{key}] = id
|
15
15
|
if cacheable
|
16
16
|
# only cache unfiltered, default api call
|
17
17
|
@attribs[:#{assoc}] = (!reload && @attribs[:#{assoc}]) || #{klass}.all(params)
|
@@ -24,7 +24,7 @@ module NCore
|
|
24
24
|
def find_#{assoc.singularize}(aid, params={})
|
25
25
|
raise UnsavedObjectError unless id
|
26
26
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
27
|
-
params
|
27
|
+
params[:#{key}] = id
|
28
28
|
#{klass}.find(aid, params)
|
29
29
|
end
|
30
30
|
M2
|
@@ -33,7 +33,7 @@ module NCore
|
|
33
33
|
def create_#{assoc.singularize}(params={})
|
34
34
|
raise UnsavedObjectError unless id
|
35
35
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
36
|
-
params
|
36
|
+
params[:#{key}] = id
|
37
37
|
#{klass}.create(params)
|
38
38
|
end
|
39
39
|
M3
|
@@ -42,7 +42,7 @@ module NCore
|
|
42
42
|
def update_#{assoc.singularize}(aid, params={})
|
43
43
|
raise UnsavedObjectError unless id
|
44
44
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
45
|
-
params
|
45
|
+
params[:#{key}] = id
|
46
46
|
#{klass}.update(aid, params)
|
47
47
|
end
|
48
48
|
M4
|
@@ -50,7 +50,7 @@ module NCore
|
|
50
50
|
def create_#{assoc.singularize}!(params={})
|
51
51
|
raise UnsavedObjectError unless id
|
52
52
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
53
|
-
params
|
53
|
+
params[:#{key}] = id
|
54
54
|
#{klass}.create!(params)
|
55
55
|
end
|
56
56
|
M5
|
@@ -58,7 +58,7 @@ module NCore
|
|
58
58
|
def update_#{assoc.singularize}!(aid, params={})
|
59
59
|
raise UnsavedObjectError unless id
|
60
60
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
61
|
-
params
|
61
|
+
params[:#{key}] = id
|
62
62
|
#{klass}.update!(aid, params)
|
63
63
|
end
|
64
64
|
M6
|
@@ -67,7 +67,7 @@ module NCore
|
|
67
67
|
def delete_#{assoc.singularize}(aid, params={})
|
68
68
|
raise UnsavedObjectError unless id
|
69
69
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
70
|
-
params
|
70
|
+
params[:#{key}] = id
|
71
71
|
#{klass}.delete(aid, params)
|
72
72
|
end
|
73
73
|
M7
|
@@ -75,15 +75,15 @@ module NCore
|
|
75
75
|
def delete_#{assoc.singularize}!(aid, params={})
|
76
76
|
raise UnsavedObjectError unless id
|
77
77
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
78
|
-
params
|
78
|
+
params[:#{key}] = id
|
79
79
|
#{klass}.delete!(aid, params)
|
80
80
|
end
|
81
81
|
M8
|
82
82
|
end
|
83
83
|
|
84
|
-
def belongs_to(assoc,
|
84
|
+
def belongs_to(assoc, class_name: nil)
|
85
85
|
assoc = assoc.to_s
|
86
|
-
klass
|
86
|
+
klass = class_name || "#{module_name}::#{assoc.camelize}"
|
87
87
|
class_eval <<-M1, __FILE__, __LINE__+1
|
88
88
|
attr :#{assoc}_id
|
89
89
|
def #{assoc}(params={})
|
data/lib/ncore/attributes.rb
CHANGED
@@ -10,6 +10,7 @@ module NCore
|
|
10
10
|
module ClassMethods
|
11
11
|
def attr(*attrs)
|
12
12
|
attrs.each do |attr|
|
13
|
+
check_existing_method(attr)
|
13
14
|
class_eval <<-AR, __FILE__, __LINE__+1
|
14
15
|
def #{attr}
|
15
16
|
self[:#{attr}]
|
@@ -20,6 +21,7 @@ module NCore
|
|
20
21
|
|
21
22
|
def attr_datetime(*attrs)
|
22
23
|
attrs.each do |attr|
|
24
|
+
check_existing_method(attr)
|
23
25
|
class_eval <<-AD, __FILE__, __LINE__+1
|
24
26
|
def #{attr}
|
25
27
|
case self[:#{attr}]
|
@@ -39,6 +41,7 @@ module NCore
|
|
39
41
|
|
40
42
|
def attr_decimal(*attrs)
|
41
43
|
attrs.each do |attr|
|
44
|
+
check_existing_method(attr)
|
42
45
|
class_eval <<-AD, __FILE__, __LINE__+1
|
43
46
|
def #{attr}
|
44
47
|
case self[:#{attr}]
|
@@ -52,10 +55,19 @@ module NCore
|
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
58
|
+
def check_existing_method(attr)
|
59
|
+
if method_defined?(attr) || private_method_defined?(attr)
|
60
|
+
sc = self
|
61
|
+
sc = sc.superclass while sc.superclass != Object
|
62
|
+
warn "Warning: Existing method #{sc.name}##{attr} being overwritten at #{caller[3]}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
55
66
|
def parse_request_params(params={}, opts={})
|
56
67
|
params = params.with_indifferent_access
|
57
68
|
req = params.delete(:request)
|
58
69
|
creds = params.delete(:credentials)
|
70
|
+
cache = params.delete(:cache)
|
59
71
|
if opts[:json_root]
|
60
72
|
if params.key?(opts[:json_root])
|
61
73
|
o = params
|
@@ -67,6 +79,7 @@ module NCore
|
|
67
79
|
end
|
68
80
|
o[:request] = req if req
|
69
81
|
o[:credentials] = creds if creds
|
82
|
+
o[:cache] = cache if cache
|
70
83
|
o
|
71
84
|
end
|
72
85
|
end
|
@@ -86,23 +99,18 @@ module NCore
|
|
86
99
|
creds_attr = attribs.delete(:credentials)
|
87
100
|
@api_creds = api_creds || creds_attr
|
88
101
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
errors: attribs.delete(:errors),
|
95
|
-
data: attribs.delete(:data) || attribs
|
96
|
-
}
|
97
|
-
end
|
98
|
-
load(load_attrs)
|
102
|
+
load(
|
103
|
+
metadata: attribs.delete(:metadata),
|
104
|
+
errors: attribs.delete(:errors),
|
105
|
+
data: attribs.delete(:data) || attribs
|
106
|
+
)
|
99
107
|
end
|
100
108
|
|
101
109
|
|
102
110
|
def attributes
|
103
111
|
Util.deep_clone(@attribs)
|
104
112
|
end
|
105
|
-
|
113
|
+
alias_method :as_json, :attributes
|
106
114
|
|
107
115
|
def [](attr)
|
108
116
|
@attribs[attr]
|
@@ -150,10 +158,10 @@ module NCore
|
|
150
158
|
end
|
151
159
|
|
152
160
|
|
153
|
-
def load(
|
154
|
-
self.metadata =
|
155
|
-
self.errors =
|
156
|
-
|
161
|
+
def load(data:, errors: nil, metadata: nil)
|
162
|
+
self.metadata = metadata || {}.with_indifferent_access
|
163
|
+
self.errors = parse_errors(errors)
|
164
|
+
data.each do |k,v|
|
157
165
|
if respond_to? "#{k}="
|
158
166
|
send "#{k}=", self.class.interpret_type(v, api_creds)
|
159
167
|
else
|
@@ -163,13 +171,28 @@ module NCore
|
|
163
171
|
self
|
164
172
|
end
|
165
173
|
|
174
|
+
def parse_errors(errors)
|
175
|
+
errors ||= []
|
176
|
+
if errors.is_a?(::ActiveModel::Errors)
|
177
|
+
errors
|
178
|
+
else
|
179
|
+
::ActiveModel::Errors.new(self).tap do |e0|
|
180
|
+
errors.each{|msg| e0.add :base, msg }
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
166
185
|
end
|
167
186
|
|
168
187
|
|
169
|
-
class BigMoney <
|
188
|
+
class BigMoney < SimpleDelegator
|
189
|
+
|
190
|
+
def initialize(*args)
|
191
|
+
__setobj__(BigDecimal(*args))
|
192
|
+
end
|
170
193
|
|
171
194
|
def to_s
|
172
|
-
if (self % BigDecimal
|
195
|
+
if (self % BigDecimal('0.01')) == 0
|
173
196
|
'%.2f' % self
|
174
197
|
else
|
175
198
|
super
|
data/lib/ncore/base.rb
CHANGED
@@ -4,8 +4,10 @@ module NCore
|
|
4
4
|
|
5
5
|
included do
|
6
6
|
extend Associations
|
7
|
+
include ActiveModel
|
7
8
|
include Attributes
|
8
9
|
include Client
|
10
|
+
include Client::Cache
|
9
11
|
include Identity
|
10
12
|
include Lifecycle
|
11
13
|
include Util
|
@@ -21,15 +23,16 @@ module NCore
|
|
21
23
|
include DeleteBulk if types.include? :delete_bulk
|
22
24
|
include Find if types.include? :find
|
23
25
|
include Update if types.include? :update
|
26
|
+
include UpdateBulk if types.include? :update_bulk
|
24
27
|
end
|
25
28
|
|
26
|
-
def
|
29
|
+
def resource_path
|
27
30
|
class_name.underscore.pluralize
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
|
-
def
|
32
|
-
"#{self.class.
|
34
|
+
def resource_path
|
35
|
+
"#{self.class.resource_path}/#{CGI.escape((id||'-').to_s)}"
|
33
36
|
end
|
34
37
|
|
35
38
|
end
|
data/lib/ncore/client.rb
CHANGED
@@ -6,11 +6,12 @@ module NCore
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
|
9
|
-
# opts - {params: {}, headers: {}, credentials: {}}
|
9
|
+
# opts - {params: {}, headers: {}, credentials: {}, cache: {}}
|
10
10
|
# unknown keys assumed to be :params if :params is missing
|
11
11
|
def request(method, url, opts={})
|
12
12
|
opts = opts.with_indifferent_access
|
13
13
|
request_credentials = opts.delete 'credentials'
|
14
|
+
cache_opts = opts.delete 'cache'
|
14
15
|
headers = opts.delete('headers') || {}
|
15
16
|
params = opts['params'] || opts
|
16
17
|
|
@@ -48,7 +49,7 @@ module NCore
|
|
48
49
|
write_timeout: 50,
|
49
50
|
}
|
50
51
|
|
51
|
-
response = execute_request(rest_opts)
|
52
|
+
response = execute_request(rest_opts, cache_opts)
|
52
53
|
parsed = parse_response(response)
|
53
54
|
[parsed, request_credentials]
|
54
55
|
end
|
@@ -58,7 +59,7 @@ module NCore
|
|
58
59
|
|
59
60
|
def retrieve_credentials
|
60
61
|
if credentials.blank?
|
61
|
-
raise
|
62
|
+
raise module_parent::Error, credentials_error_message
|
62
63
|
end
|
63
64
|
credentials
|
64
65
|
end
|
@@ -69,7 +70,7 @@ module NCore
|
|
69
70
|
|
70
71
|
def retrieve_default_url
|
71
72
|
if default_url.blank?
|
72
|
-
raise
|
73
|
+
raise module_parent::Error, credentials_error_message
|
73
74
|
end
|
74
75
|
default_url
|
75
76
|
end
|
@@ -87,12 +88,12 @@ module NCore
|
|
87
88
|
|
88
89
|
def build_query_string(params)
|
89
90
|
if params.any?
|
90
|
-
query_string = params.map do |k,v|
|
91
|
+
query_string = params.sort.map do |k,v|
|
91
92
|
if v.is_a?(Array)
|
92
93
|
if v.empty?
|
93
94
|
"#{k.to_s}[]="
|
94
95
|
else
|
95
|
-
v.map do |v2|
|
96
|
+
v.sort.map do |v2|
|
96
97
|
"#{k.to_s}[]=#{CGI::escape(v2.to_s)}"
|
97
98
|
end.join('&')
|
98
99
|
end
|
@@ -163,7 +164,7 @@ module NCore
|
|
163
164
|
end
|
164
165
|
|
165
166
|
|
166
|
-
def execute_request(rest_opts)
|
167
|
+
def execute_request(rest_opts, _)
|
167
168
|
debug_request rest_opts if debug
|
168
169
|
|
169
170
|
tries = 0
|
@@ -175,7 +176,8 @@ module NCore
|
|
175
176
|
begin
|
176
177
|
tries += 1
|
177
178
|
response = connection.request rest_opts.except(:url)
|
178
|
-
rescue Excon::Errors::SocketError, Excon::Error::Timeout,
|
179
|
+
rescue Excon::Error::Socket, Excon::Errors::SocketError, Excon::Error::Timeout,
|
180
|
+
Errno::EADDRNOTAVAIL => e
|
179
181
|
# retry when keepalive was closed
|
180
182
|
if tries <= 1 #&& e.message =~ /end of file reached/
|
181
183
|
retry
|
@@ -187,30 +189,30 @@ module NCore
|
|
187
189
|
debug_response response if debug
|
188
190
|
end
|
189
191
|
rescue Errno::ECONNRESET
|
190
|
-
raise
|
192
|
+
raise module_parent::ConnectionError, "Connection reset for #{host_for_error rest_opts[:url]} : check network or visit #{status_page}."
|
191
193
|
rescue Errno::ECONNREFUSED
|
192
|
-
raise
|
194
|
+
raise module_parent::ConnectionError, "Connection error for #{host_for_error rest_opts[:url]} : check network and DNS or visit #{status_page}."
|
193
195
|
rescue Excon::Error::Timeout => e
|
194
196
|
case e.message
|
195
197
|
when /timeout reached/
|
196
|
-
raise
|
198
|
+
raise module_parent::ConnectionError, "Connection error for #{host_for_error rest_opts[:url]} : check network and DNS or visit #{status_page}."
|
197
199
|
else
|
198
200
|
raise e
|
199
201
|
end
|
200
202
|
rescue Excon::Errors::SocketError => e
|
201
203
|
case e.message
|
202
204
|
when /Unable to verify certificate/
|
203
|
-
raise
|
205
|
+
raise module_parent::ConnectionError, "Unable to verify certificate for #{host_for_error rest_opts[:url]} : verify URL or disable SSL certificate verification (insecure)."
|
204
206
|
when /Name or service not known/, /No address associated with hostname/
|
205
|
-
raise
|
207
|
+
raise module_parent::ConnectionError, "DNS error for #{host_for_error rest_opts[:url]} : check network and DNS or visit #{status_page}."
|
206
208
|
when /Errno::ECONNREFUSED/
|
207
|
-
raise
|
209
|
+
raise module_parent::ConnectionError, "Connection error for #{host_for_error rest_opts[:url]} : check network and DNS or visit #{status_page}."
|
208
210
|
else
|
209
211
|
raise e
|
210
212
|
end
|
211
213
|
rescue SocketError => e
|
212
214
|
if e.message =~ /nodename nor servname provided/
|
213
|
-
raise
|
215
|
+
raise module_parent::ConnectionError, "DNS error for #{host_for_error rest_opts[:url]} : check network and DNS or visit #{status_page}."
|
214
216
|
else
|
215
217
|
raise e
|
216
218
|
end
|
@@ -218,21 +220,21 @@ module NCore
|
|
218
220
|
|
219
221
|
case response.status
|
220
222
|
when 401 # API auth valid; API call itself is an auth-related call and failed
|
221
|
-
raise
|
223
|
+
raise module_parent::AuthenticationFailed
|
222
224
|
when 402
|
223
|
-
raise
|
225
|
+
raise module_parent::AccountInactive, "Account inactive; login to portal to check account status."
|
224
226
|
when 403 # API auth failed or insufficient permissions
|
225
|
-
raise
|
227
|
+
raise module_parent::AccessDenied, "Access denied; check your API credentials and permissions."
|
226
228
|
when 404
|
227
|
-
raise
|
229
|
+
raise module_parent::RecordNotFound
|
228
230
|
when 409, 422
|
229
231
|
# pass through
|
230
232
|
when 429
|
231
|
-
raise
|
233
|
+
raise module_parent::RateLimited
|
232
234
|
when 400..499
|
233
|
-
raise
|
235
|
+
raise module_parent::Error, "Client error: #{response.status}\n #{response.body}"
|
234
236
|
when 500..599
|
235
|
-
raise
|
237
|
+
raise module_parent::Error, "Server error: #{response.status}\n #{response.body}"
|
236
238
|
end
|
237
239
|
response
|
238
240
|
end
|
@@ -245,20 +247,20 @@ module NCore
|
|
245
247
|
begin
|
246
248
|
json = MultiJson.load(response.body, symbolize_keys: false) || {}
|
247
249
|
rescue MultiJson::ParseError
|
248
|
-
raise
|
250
|
+
raise module_parent::Error, "Unable to parse API response; HTTP status: #{response.status}; body: #{response.body.inspect}"
|
249
251
|
end
|
250
252
|
else
|
251
253
|
begin
|
252
254
|
json = JSON.parse(response.body, symbolize_names: false) || {}
|
253
255
|
rescue JSON::ParserError
|
254
|
-
raise
|
256
|
+
raise module_parent::Error, "Unable to parse API response; HTTP status: #{response.status}; body: #{response.body.inspect}"
|
255
257
|
end
|
256
258
|
end
|
257
259
|
end
|
258
260
|
json = json.with_indifferent_access
|
259
261
|
errors = json.delete(:errors) || []
|
260
262
|
if errors.any?
|
261
|
-
errors = errors.values.flatten
|
263
|
+
errors = errors.values.flatten if errors.is_a?(Hash)
|
262
264
|
metadata, json = json, {}
|
263
265
|
else
|
264
266
|
errors = []
|
@@ -301,7 +303,7 @@ module NCore
|
|
301
303
|
else
|
302
304
|
m = 'WARNNG: SSL cert verification is disabled.'
|
303
305
|
unless verify_ssl
|
304
|
-
m += " Enable verification with: #{
|
306
|
+
m += " Enable verification with: #{module_parent}::Api.verify_ssl = true."
|
305
307
|
end
|
306
308
|
unless bundle_readable
|
307
309
|
m += " Unable to read CA bundle #{ssl_cert_bundle}."
|