error_builder 0.2.0 → 0.3.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 +11 -0
- data/README.md +23 -2
- data/lib/error_builder/engine.rb +3 -3
- data/lib/error_builder/error.rb +23 -2
- data/lib/error_builder/formats/array.rb +21 -7
- data/lib/error_builder/formats/base.rb +3 -2
- data/lib/error_builder/formats/hash.rb +18 -8
- data/lib/error_builder/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fef4923015c619400c0faaeba5412188078ad963740c10f8dcfced24a65e3a8e
|
4
|
+
data.tar.gz: 77857ce23ee12bed15d4b53e3a9c47fcff761f1b51bbfb94309e2502db8af1b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18b4a185c1d4b2f59405561539700b82e4a516ed5915d7a84ec63cef36c1b3f100c07fffe596a28a878096c657198a230c196f2f3936e2119e5ceb53c0469461
|
7
|
+
data.tar.gz: 3a68abedfdb7a80e72aec329afd3bb735153f7e5f4d5fbb8c55accbcca4f5e7887d2ee8750750da4e22c52b88f0fc8fc29f3cdbb19da2dc3ca68f6eb23e71c29
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.0] - 2025-04.06
|
4
|
+
|
5
|
+
- Changed Array and Hash formats.
|
6
|
+
- Added support for nested and flat error structures in both hash and array formats.
|
7
|
+
- Updated documentation and usage examples.
|
8
|
+
- Covered tests.
|
9
|
+
|
10
|
+
## [0.2.0] - 2025-04-05
|
11
|
+
|
12
|
+
- Provide advanced way of error collecting
|
13
|
+
|
3
14
|
## [0.1.0] - 2025-03-30
|
4
15
|
|
5
16
|
- Initial release
|
data/README.md
CHANGED
@@ -53,7 +53,7 @@ errors.add(:base, "Something went wrong")
|
|
53
53
|
|
54
54
|
3. Convert Errors to Hash or Array (depends on configuration)
|
55
55
|
```ruby
|
56
|
-
errors.to_h #=> {
|
56
|
+
errors.to_h #=> { base: ["Something went wrong"] }
|
57
57
|
```
|
58
58
|
|
59
59
|
### Including in Classes
|
@@ -71,7 +71,28 @@ end
|
|
71
71
|
|
72
72
|
my_service = MyService.new
|
73
73
|
my_service.call
|
74
|
-
my_service.errors.to_h #=> {
|
74
|
+
my_service.errors.to_h #=> { base: ["Something went wrong"] }
|
75
|
+
```
|
76
|
+
|
77
|
+
### Examples
|
78
|
+
|
79
|
+
#### Using nested keys
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
class MyService
|
83
|
+
include ErrorBuilder
|
84
|
+
|
85
|
+
def call
|
86
|
+
errors.add("user.locations[0].name", "must be present")
|
87
|
+
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
my_service = MyService.new
|
93
|
+
my_service.call
|
94
|
+
my_service.errors.to_h #=> { "user" => { "locations" => { 0 => { "name" => ["must be present"] } } } } }
|
95
|
+
my_service.errors.to_h(flat: true) #=> { "user.locations[0].name" => ["must be present"] }
|
75
96
|
```
|
76
97
|
|
77
98
|
## Development
|
data/lib/error_builder/engine.rb
CHANGED
@@ -16,12 +16,12 @@ module ErrorBuilder
|
|
16
16
|
@errors << error
|
17
17
|
end
|
18
18
|
|
19
|
-
def to_h
|
19
|
+
def to_h(flat: false)
|
20
20
|
case format
|
21
21
|
when :array
|
22
|
-
Formats::Array.new(@errors).to_h
|
22
|
+
Formats::Array.new(@errors, flat:).to_h
|
23
23
|
when :hash
|
24
|
-
Formats::Hash.new(@errors).to_h
|
24
|
+
Formats::Hash.new(@errors, flat:).to_h
|
25
25
|
else
|
26
26
|
raise ArgumentError, "Unsupported format: #{format}"
|
27
27
|
end
|
data/lib/error_builder/error.rb
CHANGED
@@ -29,9 +29,9 @@ module ErrorBuilder
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def keys
|
32
|
-
[key]
|
32
|
+
return [key] unless key.to_s.include?(".")
|
33
33
|
|
34
|
-
|
34
|
+
deflat_key
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
@@ -46,5 +46,26 @@ module ErrorBuilder
|
|
46
46
|
raise ArgumentError, "Unsupported message format: #{format}"
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
def deflat_key
|
51
|
+
key
|
52
|
+
.to_s
|
53
|
+
.split(".")
|
54
|
+
.flat_map { |part| part.split(/[\[\]]+/) }
|
55
|
+
.reject(&:empty?)
|
56
|
+
.map { |part| parse_part(part) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_part(part)
|
60
|
+
if integer?(part)
|
61
|
+
part.to_i
|
62
|
+
else
|
63
|
+
key.is_a?(String) ? part : part.to_sym
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def integer?(part)
|
68
|
+
part.match?(/\A\d+\z/)
|
69
|
+
end
|
49
70
|
end
|
50
71
|
end
|
@@ -4,22 +4,36 @@ module ErrorBuilder
|
|
4
4
|
module Formats
|
5
5
|
class Array < Base
|
6
6
|
def to_h
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
errors.each_with_object([]) do |error, array|
|
8
|
+
keys = flat ? [error.key] : error.keys
|
10
9
|
|
11
|
-
|
10
|
+
build_nested_error(array, keys, error.message)
|
11
|
+
end
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def build_nested_error(keys, value)
|
16
|
+
def build_nested_error(array, keys, value)
|
17
17
|
key = keys.shift
|
18
18
|
|
19
19
|
if keys.empty?
|
20
|
-
|
20
|
+
array << [key, value]
|
21
|
+
else
|
22
|
+
nested_array = find_or_create_nested_array(array, key)
|
23
|
+
|
24
|
+
build_nested_error(nested_array, keys, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_or_create_nested_array(array, key)
|
29
|
+
existing = array.find { |e| e.is_a?(::Array) && e.first == key }
|
30
|
+
|
31
|
+
if existing
|
32
|
+
existing[1]
|
21
33
|
else
|
22
|
-
|
34
|
+
new_array = [key, []]
|
35
|
+
array << new_array
|
36
|
+
new_array[1]
|
23
37
|
end
|
24
38
|
end
|
25
39
|
end
|
@@ -4,24 +4,34 @@ module ErrorBuilder
|
|
4
4
|
module Formats
|
5
5
|
class Hash < Base
|
6
6
|
def to_h
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
errors.each_with_object({}) do |error, hash|
|
8
|
+
keys = flat ? [error.key] : error.keys
|
10
9
|
|
11
|
-
|
10
|
+
add_nested_key(hash, keys, error.message)
|
11
|
+
end
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def
|
16
|
+
def add_nested_key(hash, keys, value)
|
17
17
|
key = keys.shift
|
18
18
|
|
19
19
|
if keys.empty?
|
20
|
-
hash
|
20
|
+
add_message(hash, key, value)
|
21
21
|
else
|
22
|
-
hash[key
|
22
|
+
hash[key] ||= {}
|
23
23
|
|
24
|
-
|
24
|
+
add_nested_key(hash[key], keys, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_message(hash, key, value)
|
29
|
+
if value.is_a?(::Array)
|
30
|
+
hash[key] ||= []
|
31
|
+
|
32
|
+
hash[key] += value
|
33
|
+
else
|
34
|
+
hash[key] = value
|
25
35
|
end
|
26
36
|
end
|
27
37
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: error_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mykhailo Marusyk
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-06 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: zeitwerk
|
@@ -55,7 +55,7 @@ metadata:
|
|
55
55
|
allowed_push_host: https://rubygems.org
|
56
56
|
homepage_uri: https://github.com/mmarusyk/error_builder
|
57
57
|
source_code_uri: https://github.com/mmarusyk/error_builder
|
58
|
-
changelog_uri: https://github.com/
|
58
|
+
changelog_uri: https://github.com/mmarusyk/error_builder/blob/main/CHANGELOG.md
|
59
59
|
rdoc_options: []
|
60
60
|
require_paths:
|
61
61
|
- lib
|