glia-errors 0.5.0 → 0.8.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/.ruby-version +1 -0
- data/README.md +23 -6
- data/glia-errors.gemspec +1 -1
- data/lib/glia/errors.rb +1 -0
- data/lib/glia/errors/client_errors.rb +89 -33
- data/lib/glia/errors/error.rb +14 -5
- data/lib/glia/errors/error_types.rb +7 -0
- data/lib/glia/errors/naming.rb +34 -0
- data/lib/glia/errors/server_errors.rb +27 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c7f5990ad3700b39cf8e730592d7a0e1bb41968015c54c648f341e329679852
|
4
|
+
data.tar.gz: 56963475888904d6d252deb42667536caeb1a7ff96c7bbb35d5204395f60723d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a09bd918e4be8fb7463523004703cf8d94e1a709f70f545f3b8f1d51384c5ba9a2be31c0a0b633042b9eec610003251b1fceb122d266c667ff18f4789487ef1
|
7
|
+
data.tar.gz: 4749bb8358fc6a1dc3f8940ae9ef5424cfdb65bef2361a529ea591890e86a8ec43a1b33207be110e7404c0ae270bd0cb197bfe11d744583ef698cce02cbbc3fe
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.7.2
|
data/README.md
CHANGED
@@ -18,7 +18,18 @@ require 'glia/errors'
|
|
18
18
|
|
19
19
|
### For Glia developers
|
20
20
|
|
21
|
-
####
|
21
|
+
#### Create Glia error manually
|
22
|
+
|
23
|
+
1. Select error from the [error list](https://internal-docs.at.samo.io/glia-errors/elixir/api-reference.html#modules)
|
24
|
+
- Documentation is for Elixir, however, the errors are the same and their initiation is very similar
|
25
|
+
2. Initialize the error according to the error documentation
|
26
|
+
|
27
|
+
Example:
|
28
|
+
```
|
29
|
+
glia_error = Glia::Errors::ResourceNotFoundError.new(resource: :engagement)
|
30
|
+
```
|
31
|
+
|
32
|
+
#### Create Glia error from `dry-validation` result
|
22
33
|
|
23
34
|
Currently 2 `dry-validation` versions are supported:
|
24
35
|
* `v0` up to `0.13`
|
@@ -29,11 +40,10 @@ schema = Dry::Validation.Schema do
|
|
29
40
|
# ...
|
30
41
|
end
|
31
42
|
result = schema.(input)
|
32
|
-
|
33
|
-
response = error.to_h
|
43
|
+
glia_error = Glia::Errors.from_dry_validation_result(result)
|
34
44
|
```
|
35
45
|
|
36
|
-
####
|
46
|
+
#### Create Glia error from `dry-validation` that contains custom errors
|
37
47
|
|
38
48
|
If you have custom `dry-validation` predicates and error messages you can specify a custom error map.
|
39
49
|
Custom error map takes priority over standard error mapping.
|
@@ -46,8 +56,15 @@ ERROR_MAP = {
|
|
46
56
|
Glia::Errors::InvalidFormatError.new(field: field)
|
47
57
|
end
|
48
58
|
}
|
49
|
-
|
50
|
-
|
59
|
+
glia_error = Glia::Errors.from_dry_validation_result(result, ERROR_MAP)
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Convert Glia error to a hash
|
63
|
+
|
64
|
+
You can use this to convert Glia error to hash, so that later it can be converted to JSON.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
glia_error.to_h
|
51
68
|
```
|
52
69
|
|
53
70
|
### For REST API integrators
|
data/glia-errors.gemspec
CHANGED
data/lib/glia/errors.rb
CHANGED
@@ -7,8 +7,8 @@ module Glia
|
|
7
7
|
def initialize(error_details:, message: nil)
|
8
8
|
super(
|
9
9
|
type: INPUT_VALIDATION_ERROR,
|
10
|
-
ref:
|
11
|
-
message: message,
|
10
|
+
ref: create_ref(INPUT_VALIDATION_ERROR),
|
11
|
+
message: message || 'Input is invalid',
|
12
12
|
error_details: error_details
|
13
13
|
)
|
14
14
|
end
|
@@ -18,8 +18,8 @@ module Glia
|
|
18
18
|
def initialize(field:, message: nil)
|
19
19
|
super(
|
20
20
|
type: INVALID_NUMBER_ERROR,
|
21
|
-
ref:
|
22
|
-
message: "#{humanize(field)}
|
21
|
+
ref: create_ref(INVALID_NUMBER_ERROR),
|
22
|
+
message: message || "#{Naming.humanize(field)} value is invalid"
|
23
23
|
)
|
24
24
|
end
|
25
25
|
end
|
@@ -28,8 +28,8 @@ module Glia
|
|
28
28
|
def initialize(field:, message: nil)
|
29
29
|
super(
|
30
30
|
type: INVALID_VALUE_ERROR,
|
31
|
-
ref:
|
32
|
-
message: "#{humanize(field)}
|
31
|
+
ref: create_ref(INVALID_VALUE_ERROR),
|
32
|
+
message: message || "#{Naming.humanize(field)} value is invalid"
|
33
33
|
)
|
34
34
|
end
|
35
35
|
end
|
@@ -38,8 +38,8 @@ module Glia
|
|
38
38
|
def initialize(field:, message: nil)
|
39
39
|
super(
|
40
40
|
type: INVALID_LENGTH_ERROR,
|
41
|
-
ref:
|
42
|
-
message: "#{humanize(field)}
|
41
|
+
ref: create_ref(INVALID_LENGTH_ERROR),
|
42
|
+
message: message || "#{Naming.humanize(field)} length is invalid"
|
43
43
|
)
|
44
44
|
end
|
45
45
|
end
|
@@ -54,13 +54,34 @@ module Glia
|
|
54
54
|
|
55
55
|
def initialize(field:, format: nil, message: nil)
|
56
56
|
default_message =
|
57
|
-
|
57
|
+
if format
|
58
|
+
"has invalid format, required format is #{humanize_format(format)}"
|
59
|
+
else
|
60
|
+
'has invalid format'
|
61
|
+
end
|
58
62
|
super(
|
59
63
|
type: INVALID_FORMAT_ERROR,
|
60
|
-
ref:
|
61
|
-
message: "#{humanize(field)} "
|
64
|
+
ref: create_ref(INVALID_FORMAT_ERROR),
|
65
|
+
message: message || "#{Naming.humanize(field)} #{default_message}"
|
62
66
|
)
|
63
67
|
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def humanize_format(format)
|
72
|
+
case format
|
73
|
+
when Formats::DATE
|
74
|
+
'ISO-8601 date'
|
75
|
+
when Formats::TIME
|
76
|
+
'ISO-8601 time'
|
77
|
+
when Formats::DATE_TIME
|
78
|
+
'ISO-8601 date and time'
|
79
|
+
when Formats::UUID
|
80
|
+
'UUID'
|
81
|
+
else
|
82
|
+
raise 'Unexpected InvalidFormatError format'
|
83
|
+
end
|
84
|
+
end
|
64
85
|
end
|
65
86
|
|
66
87
|
class InvalidTypeError < Error
|
@@ -76,8 +97,9 @@ module Glia
|
|
76
97
|
def initialize(field:, type:, message: nil)
|
77
98
|
super(
|
78
99
|
type: INVALID_TYPE_ERROR,
|
79
|
-
ref:
|
80
|
-
message: "#{humanize(field)}
|
100
|
+
ref: create_ref(INVALID_TYPE_ERROR),
|
101
|
+
message: message || "#{Naming.humanize(field)} must be of type #{type}",
|
102
|
+
error_details: { type: type }
|
81
103
|
)
|
82
104
|
end
|
83
105
|
end
|
@@ -86,8 +108,8 @@ module Glia
|
|
86
108
|
def initialize(field:, message: nil)
|
87
109
|
super(
|
88
110
|
type: MISSING_VALUE_ERROR,
|
89
|
-
ref:
|
90
|
-
message: "#{humanize(field)}
|
111
|
+
ref: create_ref(MISSING_VALUE_ERROR),
|
112
|
+
message: message || "#{Naming.humanize(field)} is missing"
|
91
113
|
)
|
92
114
|
end
|
93
115
|
end
|
@@ -96,18 +118,20 @@ module Glia
|
|
96
118
|
def initialize(field:, message: nil)
|
97
119
|
super(
|
98
120
|
type: UNKNOWN_ERROR,
|
99
|
-
ref:
|
100
|
-
message: "#{humanize(field)}
|
121
|
+
ref: create_ref(UNKNOWN_ERROR),
|
122
|
+
message: message || "#{Naming.humanize(field)} validation failed with unknown error"
|
101
123
|
)
|
102
124
|
end
|
103
125
|
end
|
104
126
|
|
105
127
|
class ResourceNotFoundError < Error
|
106
128
|
def initialize(resource:, message: nil)
|
129
|
+
assert_snake_case(resource)
|
130
|
+
|
107
131
|
super(
|
108
132
|
type: RESOURCE_NOT_FOUND_ERROR,
|
109
|
-
ref:
|
110
|
-
message: "#{humanize(resource)}
|
133
|
+
ref: create_ref(RESOURCE_NOT_FOUND_ERROR),
|
134
|
+
message: message || "#{Naming.humanize(resource)} not found",
|
111
135
|
error_details: { resource: resource }
|
112
136
|
)
|
113
137
|
end
|
@@ -115,10 +139,12 @@ module Glia
|
|
115
139
|
|
116
140
|
class NotVerifiedError < Error
|
117
141
|
def initialize(resource:, message: nil)
|
142
|
+
assert_snake_case(resource)
|
143
|
+
|
118
144
|
super(
|
119
145
|
type: NOT_VERIFIED_ERROR,
|
120
|
-
ref:
|
121
|
-
message: "#{humanize(resource)}
|
146
|
+
ref: create_ref(NOT_VERIFIED_ERROR),
|
147
|
+
message: message || "#{Naming.humanize(resource)} is not verified",
|
122
148
|
error_details: { resource: resource }
|
123
149
|
)
|
124
150
|
end
|
@@ -126,25 +152,30 @@ module Glia
|
|
126
152
|
|
127
153
|
class RemainingAssociationError < Error
|
128
154
|
def initialize(resource:, associated_resource:, message: nil)
|
155
|
+
assert_snake_case(resource)
|
156
|
+
assert_snake_case(associated_resource)
|
157
|
+
|
129
158
|
default_message =
|
130
159
|
"cannot be modified/deleted because it is associated to one or more #{
|
131
|
-
humanize(associated_resource)
|
160
|
+
Naming.humanize(associated_resource)
|
132
161
|
}(s)"
|
133
162
|
super(
|
134
163
|
type: REMAINING_ASSOCIATION_ERROR,
|
135
|
-
ref:
|
136
|
-
message: "#{humanize(resource)} "
|
164
|
+
ref: create_ref(REMAINING_ASSOCIATION_ERROR),
|
165
|
+
message: message || "#{Naming.humanize(resource)} #{default_message}",
|
137
166
|
error_details: { resource: resource, associated_resource: associated_resource }
|
138
167
|
)
|
139
168
|
end
|
140
169
|
end
|
141
170
|
|
142
|
-
class
|
171
|
+
class ResourceLimitExceededError < Error
|
143
172
|
def initialize(resource:, max:, message: nil)
|
173
|
+
assert_snake_case(resource)
|
174
|
+
|
144
175
|
super(
|
145
176
|
type: LIMIT_EXCEEDED_ERROR,
|
146
|
-
ref:
|
147
|
-
message: "#{humanize(resource)}
|
177
|
+
ref: create_ref(LIMIT_EXCEEDED_ERROR),
|
178
|
+
message: message || "#{Naming.humanize(resource)} count must not exceed #{max}",
|
148
179
|
error_details: { resource: resource, max: max }
|
149
180
|
)
|
150
181
|
end
|
@@ -152,10 +183,12 @@ module Glia
|
|
152
183
|
|
153
184
|
class ResourceAlreadyExistsError < Error
|
154
185
|
def initialize(resource:, message: nil)
|
186
|
+
assert_snake_case(resource)
|
187
|
+
|
155
188
|
super(
|
156
189
|
type: RESOURCE_ALREADY_EXISTS_ERROR,
|
157
|
-
ref:
|
158
|
-
message: "#{humanize(resource)}
|
190
|
+
ref: create_ref(RESOURCE_ALREADY_EXISTS_ERROR),
|
191
|
+
message: message || "#{Naming.humanize(resource)} already exists",
|
159
192
|
error_details: { resource: resource }
|
160
193
|
)
|
161
194
|
end
|
@@ -163,10 +196,13 @@ module Glia
|
|
163
196
|
|
164
197
|
class InvalidResourceStateError < Error
|
165
198
|
def initialize(resource:, state:, message: nil)
|
199
|
+
assert_snake_case(resource)
|
200
|
+
assert_snake_case(state)
|
201
|
+
|
166
202
|
super(
|
167
203
|
type: INVALID_RESOURCE_STATE_ERROR,
|
168
|
-
ref:
|
169
|
-
message: "#{humanize(resource)}
|
204
|
+
ref: create_ref(INVALID_RESOURCE_STATE_ERROR),
|
205
|
+
message: message || "#{Naming.humanize(resource)} is in invalid state: #{state}",
|
170
206
|
error_details: { resource: resource, state: state }
|
171
207
|
)
|
172
208
|
end
|
@@ -176,7 +212,7 @@ module Glia
|
|
176
212
|
def initialize(message: nil)
|
177
213
|
super(
|
178
214
|
type: AUTHORIZATION_ERROR,
|
179
|
-
ref:
|
215
|
+
ref: create_ref(AUTHORIZATION_ERROR),
|
180
216
|
message: message || 'You do not have permissions to perform the action'
|
181
217
|
)
|
182
218
|
end
|
@@ -186,11 +222,31 @@ module Glia
|
|
186
222
|
def initialize(message: nil)
|
187
223
|
super(
|
188
224
|
type: RECIPIENT_OPTED_OUT_ERROR,
|
189
|
-
ref:
|
225
|
+
ref: create_ref(RECIPIENT_OPTED_OUT_ERROR),
|
190
226
|
message: message || 'Recipient has opted out'
|
191
227
|
)
|
192
228
|
end
|
193
229
|
end
|
230
|
+
|
231
|
+
class RouteNotFoundError < Error
|
232
|
+
def initialize(message: nil)
|
233
|
+
super(
|
234
|
+
type: ROUTE_NOT_FOUND_ERROR,
|
235
|
+
ref: create_ref(ROUTE_NOT_FOUND_ERROR),
|
236
|
+
message: message || 'Route not found'
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
class MalformedInputError < Error
|
242
|
+
def initialize(message: nil)
|
243
|
+
super(
|
244
|
+
type: MALFORMED_INPUT_ERROR,
|
245
|
+
ref: create_ref(MALFORMED_INPUT_ERROR),
|
246
|
+
message: message || 'Request is malformed'
|
247
|
+
)
|
248
|
+
end
|
249
|
+
end
|
194
250
|
# rubocop:enable Style/Documentation
|
195
251
|
end
|
196
252
|
end
|
data/lib/glia/errors/error.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './naming'
|
4
|
+
|
3
5
|
module Glia
|
4
6
|
module Errors
|
5
7
|
# Base error
|
6
8
|
class Error
|
9
|
+
SNAKE_CASE_REGEX = /^[a-z0-9]+(_[a-z0-9]+)*$/.freeze
|
7
10
|
attr_reader :type, :ref, :message, :error_details
|
8
11
|
|
9
12
|
def initialize(type:, ref:, message: nil, error_details: nil)
|
@@ -38,13 +41,19 @@ module Glia
|
|
38
41
|
end
|
39
42
|
|
40
43
|
def primitive?(details)
|
41
|
-
details.nil? ||
|
44
|
+
details.nil? ||
|
45
|
+
[TrueClass, FalseClass, String, Integer, Float, Symbol].include?(details.class)
|
46
|
+
end
|
47
|
+
|
48
|
+
def assert_snake_case(value)
|
49
|
+
return if value.to_s.match(SNAKE_CASE_REGEX)
|
50
|
+
|
51
|
+
raise ArgumentError, "Expected '#{value}' to be in snake case"
|
42
52
|
end
|
43
53
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
value.to_s.capitalize.gsub('_', ' ')
|
54
|
+
def create_ref(type)
|
55
|
+
fragment = type.gsub('_', '-')
|
56
|
+
"https://docs.glia.com/glia-dev/reference/errors##{fragment}"
|
48
57
|
end
|
49
58
|
end
|
50
59
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module Glia
|
4
4
|
module Errors
|
5
|
+
# Client errors
|
5
6
|
INPUT_VALIDATION_ERROR = 'input_validation_error'
|
6
7
|
INVALID_TYPE_ERROR = 'invalid_type_error'
|
7
8
|
INVALID_NUMBER_ERROR = 'invalid_number_error'
|
@@ -18,5 +19,11 @@ module Glia
|
|
18
19
|
INVALID_RESOURCE_STATE_ERROR = 'invalid_resource_state_error'
|
19
20
|
AUTHORIZATION_ERROR = 'authorization_error'
|
20
21
|
RECIPIENT_OPTED_OUT_ERROR = 'recipient_opted_out_error'
|
22
|
+
ROUTE_NOT_FOUND_ERROR = 'route_not_found_error'
|
23
|
+
MALFORMED_INPUT_ERROR = 'malformed_input_error'
|
24
|
+
|
25
|
+
# Server errors
|
26
|
+
INTERNAL_SERVER_ERROR = 'internal_server_error'
|
27
|
+
SERVICE_UNAVAILABLE_ERROR = 'service_unavailable_error'
|
21
28
|
end
|
22
29
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glia
|
4
|
+
module Errors
|
5
|
+
# Utilities for variable and resouce names
|
6
|
+
module Naming
|
7
|
+
# Converts from camel_case to more human readable value
|
8
|
+
# first_name => "First name"
|
9
|
+
# site_id => "Site ID"
|
10
|
+
def self.humanize(value)
|
11
|
+
result = value.to_s.split('_').map { |word| upcase_if_abbreviation(word) }.join(' ')
|
12
|
+
|
13
|
+
upcase_first(result)
|
14
|
+
end
|
15
|
+
|
16
|
+
ABBREVIATIONS = %w[id uuid saml sip sms mms].freeze
|
17
|
+
PLURAL_ABBREVIATIONS = %w[ids uuids].freeze
|
18
|
+
|
19
|
+
private_class_method def self.upcase_if_abbreviation(value)
|
20
|
+
if ABBREVIATIONS.include?(value)
|
21
|
+
value.upcase
|
22
|
+
elsif PLURAL_ABBREVIATIONS.include?(value)
|
23
|
+
value[0..-2].upcase.concat('s')
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private_class_method def self.upcase_first(value)
|
30
|
+
value[0].upcase.concat(value[1..-1])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glia
|
4
|
+
module Errors
|
5
|
+
# rubocop:disable Style/Documentation
|
6
|
+
class InternalServerError < Error
|
7
|
+
def initialize(message: nil)
|
8
|
+
super(
|
9
|
+
type: INTERNAL_SERVER_ERROR,
|
10
|
+
ref: create_ref(INTERNAL_SERVER_ERROR),
|
11
|
+
message: message || 'Internal server error'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ServiceUnavailableError < Error
|
17
|
+
def initialize(message: nil)
|
18
|
+
super(
|
19
|
+
type: SERVICE_UNAVAILABLE_ERROR,
|
20
|
+
ref: create_ref(SERVICE_UNAVAILABLE_ERROR),
|
21
|
+
message: message || 'Service unavailable'
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# rubocop:enable Style/Documentation
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glia-errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Glia TechMovers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ''
|
14
14
|
email:
|
@@ -22,6 +22,7 @@ files:
|
|
22
22
|
- ".prettierrc"
|
23
23
|
- ".rspec"
|
24
24
|
- ".rubocop.yml"
|
25
|
+
- ".ruby-version"
|
25
26
|
- ".travis.yml"
|
26
27
|
- Appraisals
|
27
28
|
- Gemfile
|
@@ -36,6 +37,8 @@ files:
|
|
36
37
|
- lib/glia/errors/error.rb
|
37
38
|
- lib/glia/errors/error_types.rb
|
38
39
|
- lib/glia/errors/mapper.rb
|
40
|
+
- lib/glia/errors/naming.rb
|
41
|
+
- lib/glia/errors/server_errors.rb
|
39
42
|
homepage:
|
40
43
|
licenses:
|
41
44
|
- MIT
|
@@ -55,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
58
|
- !ruby/object:Gem::Version
|
56
59
|
version: '0'
|
57
60
|
requirements: []
|
58
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.1.4
|
59
62
|
signing_key:
|
60
63
|
specification_version: 4
|
61
64
|
summary: Glia REST API errors
|