Skip to content

Commit 90f0f8f

Browse files
authored
Merge pull request #1049 from cerebris/raise_errors_earlier
Tightens the error handling on request parsing.
2 parents c145109 + d177c22 commit 90f0f8f

File tree

3 files changed

+21
-36
lines changed

3 files changed

+21
-36
lines changed

lib/jsonapi/request_parser.rb

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ def parse_fields(resource_klass, fields)
281281
fail JSONAPI::Exceptions::InvalidFieldFormat.new(error_object_overrides)
282282
end
283283

284-
errors = []
285284
# Validate the fields
286285
validated_fields = {}
287286
extracted_fields.each do |type, values|
@@ -293,31 +292,27 @@ def parse_fields(resource_klass, fields)
293292
end
294293
type_resource = Resource.resource_klass_for(resource_klass.module_path + underscored_type.to_s)
295294
rescue NameError
296-
errors.concat(JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides).errors)
297-
rescue JSONAPI::Exceptions::InvalidResource => e
298-
errors.concat(e.errors)
295+
fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
299296
end
300297

301298
if type_resource.nil?
302-
errors.concat(JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides).errors)
299+
fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
303300
else
304301
unless values.nil?
305302
valid_fields = type_resource.fields.collect { |key| format_key(key) }
306303
values.each do |field|
307304
if valid_fields.include?(field)
308305
validated_fields[type].push unformat_key(field)
309306
else
310-
errors.concat(JSONAPI::Exceptions::InvalidField.new(type, field, error_object_overrides).errors)
307+
fail JSONAPI::Exceptions::InvalidField.new(type, field, error_object_overrides)
311308
end
312309
end
313310
else
314-
errors.concat(JSONAPI::Exceptions::InvalidField.new(type, 'nil', error_object_overrides).errors)
311+
fail JSONAPI::Exceptions::InvalidField.new(type, 'nil', error_object_overrides)
315312
end
316313
end
317314
end
318315

319-
fail JSONAPI::Exceptions::Errors.new(errors) unless errors.empty?
320-
321316
validated_fields.deep_transform_keys { |key| unformat_key(key) }
322317
end
323318

@@ -389,7 +384,7 @@ def parse_filters(resource_klass, filters)
389384
if resource_klass._allowed_filter?(filter)
390385
parsed_filters[filter] = value
391386
else
392-
@errors.concat(JSONAPI::Exceptions::FilterNotAllowed.new(filter).errors)
387+
fail JSONAPI::Exceptions::FilterNotAllowed.new(filter)
393388
end
394389
end
395390

@@ -432,8 +427,7 @@ def check_sort_criteria(resource_klass, sort_criteria)
432427
sort_field = sort_criteria[:field]
433428

434429
unless resource_klass.sortable_field?(sort_field.to_sym, context)
435-
@errors.concat(JSONAPI::Exceptions::InvalidSortCriteria
436-
.new(format_key(resource_klass._type), sort_field).errors)
430+
fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(resource_klass._type), sort_field)
437431
end
438432
end
439433

@@ -582,16 +576,14 @@ def unformat_value(resource_klass, attribute, value)
582576
def verify_permitted_params(params, allowed_fields)
583577
formatted_allowed_fields = allowed_fields.collect { |field| format_key(field).to_sym }
584578
params_not_allowed = []
585-
param_errors = []
586579

587580
params.each do |key, value|
588581
case key.to_s
589582
when 'relationships'
590583
value.keys.each do |links_key|
591584
unless formatted_allowed_fields.include?(links_key.to_sym)
592585
if JSONAPI.configuration.raise_if_parameters_not_allowed
593-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
594-
links_key, error_object_overrides).errors
586+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(links_key, error_object_overrides)
595587
else
596588
params_not_allowed.push(links_key)
597589
value.delete links_key
@@ -602,8 +594,7 @@ def verify_permitted_params(params, allowed_fields)
602594
value.each do |attr_key, _attr_value|
603595
unless formatted_allowed_fields.include?(attr_key.to_sym)
604596
if JSONAPI.configuration.raise_if_parameters_not_allowed
605-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
606-
attr_key, error_object_overrides).errors
597+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key, error_object_overrides)
607598
else
608599
params_not_allowed.push(attr_key)
609600
value.delete attr_key
@@ -614,27 +605,23 @@ def verify_permitted_params(params, allowed_fields)
614605
when 'id'
615606
unless formatted_allowed_fields.include?(:id)
616607
if JSONAPI.configuration.raise_if_parameters_not_allowed
617-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
618-
:id, error_object_overrides).errors
608+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(:id, error_object_overrides)
619609
else
620610
params_not_allowed.push(:id)
621611
params.delete :id
622612
end
623613
end
624614
else
625615
if JSONAPI.configuration.raise_if_parameters_not_allowed
626-
param_errors += JSONAPI::Exceptions::ParameterNotAllowed.new(
627-
key, error_object_overrides).errors
616+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(key, error_object_overrides)
628617
else
629618
params_not_allowed.push(key)
630619
params.delete key
631620
end
632621
end
633622
end
634623

635-
if param_errors.length > 0
636-
fail JSONAPI::Exceptions::Errors.new(param_errors)
637-
elsif params_not_allowed.length > 0
624+
if params_not_allowed.length > 0
638625
params_not_allowed_warnings = params_not_allowed.map do |param|
639626
JSONAPI::Warning.new(code: JSONAPI::PARAM_NOT_ALLOWED,
640627
title: 'Param not allowed',

test/controllers/controller_test.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,6 @@ def test_update_unpermitted_attributes
18181818
}
18191819

18201820
assert_response :bad_request
1821-
assert_match /author is not allowed./, response.body
18221821
assert_match /subject is not allowed./, response.body
18231822
end
18241823

test/unit/jsonapi_request/jsonapi_request_test.rb

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def test_parse_dasherized_with_underscored_fields
153153
}
154154
)
155155

156-
e = assert_raises JSONAPI::Exceptions::Errors do
156+
e = assert_raises JSONAPI::Exceptions::InvalidField do
157157
request.parse_fields(ExpenseEntryResource, params[:fields])
158158
end
159159
refute e.errors.empty?
@@ -178,7 +178,7 @@ def test_parse_dasherized_with_underscored_resource
178178
key_formatter: JSONAPI::Formatter.formatter_for(:dasherized_key)
179179
}
180180
)
181-
e = assert_raises JSONAPI::Exceptions::Errors do
181+
e = assert_raises JSONAPI::Exceptions::InvalidResource do
182182
request.parse_fields(ExpenseEntryResource, params[:fields])
183183
end
184184
refute e.errors.empty?
@@ -194,10 +194,10 @@ def test_parse_filters_with_valid_filters
194194

195195
def test_parse_filters_with_non_valid_filter
196196
setup_request
197-
filters = @request.parse_filters(CatResource, {breed: 'Whiskers'}) # breed is not a set filter
198-
assert_equal(filters, {})
199-
assert_equal(@request.errors.count, 1)
200-
assert_equal(@request.errors.first.title, "Filter not allowed")
197+
e = assert_raises JSONAPI::Exceptions::FilterNotAllowed do
198+
@request.parse_filters(CatResource, {breed: 'Whiskers'}) # breed is not a set filter
199+
end
200+
assert_equal 'breed is not allowed.', e.errors[0].detail
201201
end
202202

203203
def test_parse_filters_with_no_filters
@@ -224,11 +224,10 @@ def test_parse_sort_with_valid_sorts
224224

225225
def test_parse_sort_with_resource_validated_sorts
226226
setup_request
227-
sort_criteria = @request.parse_sort_criteria(TreeResource, "sort66,name")
228-
assert_equal(@request.errors.count, 1)
229-
assert_equal(@request.errors.first.title, "Invalid sort criteria")
230-
assert_equal(@request.errors.first.detail, "name is not a valid sort criteria for trees")
231-
assert_equal(sort_criteria, [{:field=>"sort66", :direction=>:asc}, {:field=>"name", :direction=>:asc}])
227+
e = assert_raises JSONAPI::Exceptions::InvalidSortCriteria do
228+
@request.parse_sort_criteria(TreeResource, "sort66,name")
229+
end
230+
assert_equal 'name is not a valid sort criteria for trees', e.errors[0].detail
232231
end
233232

234233
def test_parse_sort_with_relationships

0 commit comments

Comments
 (0)