Skip to content

Commit fd4c839

Browse files
senid231chingor13
authored andcommitted
correct handling of errors with source/pointer "/data" (#277)
correct handling of source/parameter
1 parent c84e751 commit fd4c839

File tree

3 files changed

+121
-16
lines changed

3 files changed

+121
-16
lines changed

lib/json_api_client/error_collector.rb

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,27 @@ def detail
3333
end
3434

3535
def source_parameter
36-
source.fetch(:parameter) do
37-
source[:pointer] ?
38-
source[:pointer].split("/").last :
39-
nil
40-
end
36+
source[:parameter]
4137
end
4238

4339
def source_pointer
44-
source.fetch(:pointer) do
45-
source[:parameter] ?
46-
"/data/attributes/#{source[:parameter]}" :
47-
nil
40+
source[:pointer]
41+
end
42+
43+
def error_key
44+
if source_pointer && source_pointer != "/data"
45+
source_pointer.split("/").last
46+
else
47+
"base"
48+
end
49+
end
50+
51+
def error_msg
52+
msg = title || detail || "invalid"
53+
if source_parameter
54+
"#{source_parameter} #{msg}"
55+
else
56+
msg
4857
end
4958
end
5059

@@ -74,7 +83,7 @@ def full_messages
7483

7584
def [](source)
7685
map do |error|
77-
error.source_parameter == source
86+
error.error_key == source
7887
end
7988
end
8089

lib/json_api_client/resource.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,8 @@ def relationships_for_serialization
502502

503503
def fill_errors
504504
last_result_set.errors.each do |error|
505-
if error.source_parameter
506-
errors.add(self.class.key_formatter.unformat(error.source_parameter), error.title || error.detail)
507-
else
508-
errors.add(:base, error.title || error.detail)
509-
end
505+
key = self.class.key_formatter.unformat(error.error_key)
506+
errors.add(key, error.error_msg)
510507
end
511508
end
512509
end

test/unit/error_collector_test.rb

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ def test_can_handle_errors
9494
assert article.errors.present?
9595
assert_equal 2, article.errors.size
9696

97+
assert_equal ["Email address is invalid."], article.errors[:email_address]
98+
assert_equal ["Title already taken"], article.errors[:base]
99+
97100
error = article.last_result_set.errors.first
98101
assert_equal "1234-abcd", error.id
99102
assert_equal "http://example.com/help/errors/1337", error.about
@@ -102,7 +105,7 @@ def test_can_handle_errors
102105
assert_equal "Email address is invalid.", error.title
103106
assert_equal "Email address 'bar' is not a valid email address.", error.detail
104107
assert_equal "/data/attributes/email_address", error.source_pointer
105-
assert_equal "email_address", error.source_parameter
108+
assert_nil error.source_parameter
106109
assert error.meta.is_a?(JsonApiClient::MetaData)
107110
assert_equal "asdf", error.meta.qwer
108111

@@ -118,6 +121,100 @@ def test_can_handle_errors
118121
assert error.meta.is_a?(JsonApiClient::MetaData)
119122
end
120123

124+
def test_can_handle_generic_error
125+
stub_request(:post, "http://example.com/articles")
126+
.with(headers: {content_type: "application/vnd.api+json", accept: "application/vnd.api+json"}, body: {
127+
data: {
128+
type: "articles",
129+
attributes: {
130+
title: "Rails is Omakase",
131+
email_address: "bar"
132+
}
133+
}
134+
}.to_json)
135+
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
136+
errors: [
137+
{
138+
id: "1234-abcd",
139+
status: "422",
140+
code: "1337",
141+
title: "You can't create this record",
142+
detail: "You can't create this record",
143+
source: {
144+
pointer: "/data"
145+
}
146+
}
147+
]
148+
}.to_json)
149+
150+
article = Article.create({
151+
title: "Rails is Omakase",
152+
email_address: "bar"
153+
})
154+
refute article.persisted?
155+
assert article.errors.present?
156+
assert_equal 1, article.errors.size
157+
158+
assert_equal ["You can't create this record"], article.errors[:base]
159+
160+
error = article.last_result_set.errors.first
161+
assert_equal "1234-abcd", error.id
162+
assert_nil error.about
163+
assert_equal "422", error.status
164+
assert_equal "1337", error.code
165+
assert_equal "You can't create this record", error.title
166+
assert_equal "You can't create this record", error.detail
167+
assert_equal "/data", error.source_pointer
168+
assert_nil error.source_parameter
169+
end
170+
171+
def test_can_handle_parameter_error
172+
stub_request(:post, "http://example.com/articles")
173+
.with(headers: {content_type: "application/vnd.api+json", accept: "application/vnd.api+json"}, body: {
174+
data: {
175+
type: "articles",
176+
attributes: {
177+
title: "Rails is Omakase",
178+
email_address: "bar"
179+
}
180+
}
181+
}.to_json)
182+
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
183+
errors: [
184+
{
185+
id: "1234-abcd",
186+
status: "400",
187+
code: "1337",
188+
title: "bar is required",
189+
detail: "bar include is required for creation",
190+
source: {
191+
parameter: "include"
192+
}
193+
}
194+
]
195+
}.to_json)
196+
197+
article = Article.create({
198+
title: "Rails is Omakase",
199+
email_address: "bar"
200+
})
201+
refute article.persisted?
202+
assert article.errors.present?
203+
assert_equal 1, article.errors.size
204+
205+
assert_equal ["include bar is required"], article.errors[:base]
206+
207+
error = article.last_result_set.errors.first
208+
assert_equal "1234-abcd", error.id
209+
assert_nil error.about
210+
assert_equal "400", error.status
211+
assert_equal "1337", error.code
212+
assert_equal "bar is required", error.title
213+
assert_equal "bar include is required for creation", error.detail
214+
assert_nil error.source_pointer
215+
assert_equal "include", error.source_parameter
216+
end
217+
121218
def test_can_handle_explicit_null_error_values
122219
stub_request(:post, "http://example.com/articles")
123220
.with(headers: {content_type: "application/vnd.api+json", accept: "application/vnd.api+json"}, body: {
@@ -152,6 +249,8 @@ def test_can_handle_explicit_null_error_values
152249
assert article.errors.present?
153250
assert_equal 1, article.errors.size
154251

252+
assert_equal ["invalid"], article.errors[:base]
253+
155254
error = article.last_result_set.errors.first
156255
assert_equal "1337", error.id
157256

0 commit comments

Comments
 (0)