Skip to content

Commit 1c771fd

Browse files
committed
Added better error messaging. Shows full path of invalid param
1 parent a904fcc commit 1c771fd

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

lib/rails_param/param.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,20 @@ module Param
44
DEFAULT_PRECISION = 14
55

66
class InvalidParameterError < StandardError
7-
attr_accessor :param, :options
7+
attr_accessor :param, :options, :full_path_array
8+
9+
def initialize(msg)
10+
super(msg)
11+
@full_path_array = []
12+
end
13+
14+
def full_path
15+
str = ""
16+
full_path_array.each_with_index do |a, index|
17+
str += (index == 0) ? a : "[#{a}]"
18+
end
19+
str
20+
end
821
end
922

1023
class MockController
@@ -13,6 +26,8 @@ class MockController
1326
end
1427

1528
def param!(name, type, options = {}, &block)
29+
evaluating_index = nil # used to keep track of array indexes
30+
1631
# keep index for validating elements if integer
1732
name = name.to_s unless name.is_a? Integer
1833

@@ -46,6 +61,7 @@ def param!(name, type, options = {}, &block)
4661
if type == Array
4762
params[name].each_with_index do |element, i|
4863
if element.is_a?(Hash)
64+
evaluating_index = i
4965
recurse element, &block
5066
else
5167
# supply index as key unless value is hash
@@ -59,6 +75,10 @@ def param!(name, type, options = {}, &block)
5975
params[name]
6076

6177
rescue InvalidParameterError => exception
78+
unless evaluating_index.nil?
79+
exception.full_path_array.unshift(evaluating_index)
80+
end
81+
exception.full_path_array.unshift(name)
6282
exception.param ||= name
6383
exception.options ||= options
6484
raise exception

spec/rails_param/param_spec.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,5 +477,84 @@ def self.validate!(value)
477477
end
478478
end
479479
end
480+
481+
describe 'exception full_path_array' do
482+
it 'has the proper full path with single param check' do
483+
allow(controller).to receive(:params).and_return({"price" => "abc"})
484+
begin
485+
controller.param! :price, Integer, required: true
486+
rescue RailsParam::Param::InvalidParameterError => e
487+
expect(e.full_path_array).to eql ["price"]
488+
end
489+
end
490+
491+
it 'has the proper full path when using arrays with hashes' do
492+
params = {
493+
'array' => [
494+
{'object'=>{ 'num' => '1', 'float' => '1.4' }},
495+
{'object'=>{ 'num' => '2', 'float' => 'abc' }}
496+
]
497+
}
498+
allow(controller).to receive(:params).and_return(params)
499+
begin
500+
controller.param! :array, Array do |a|
501+
a.param! :object, Hash do |h|
502+
h.param! :num, Integer, required: true
503+
h.param! :float, Float, required: true
504+
end
505+
end
506+
rescue RailsParam::Param::InvalidParameterError => e
507+
expect(e.full_path_array).to eql ["array", 1, "object", "float"]
508+
end
509+
end
510+
511+
it 'has the proper full path when using arrays with primitive types' do
512+
params = {
513+
'array' => ["abc"]
514+
}
515+
allow(controller).to receive(:params).and_return(params)
516+
begin
517+
controller.param! :array, Array do |array, index|
518+
array.param! index, Integer, :required => true
519+
end
520+
rescue RailsParam::Param::InvalidParameterError => e
521+
expect(e.full_path_array).to eql ['array', 0]
522+
end
523+
end
524+
525+
it 'has the proper full path when using hashes' do
526+
params = {
527+
'hash' => {
528+
'hash2'=> {'integers' => ['123', 'abc'] }
529+
}
530+
}
531+
allow(controller).to receive(:params).and_return(params)
532+
begin
533+
controller.param! :hash, Hash do |a|
534+
a.param! :hash2, Hash do |h|
535+
h.param! :integers, Array do |array, index|
536+
array.param! index, Integer
537+
end
538+
end
539+
end
540+
rescue RailsParam::Param::InvalidParameterError => e
541+
expect(e.full_path_array).to eql ["hash", "hash2", "integers", 1]
542+
end
543+
end
544+
end
545+
546+
describe 'full_path' do
547+
it 'has the correct full path for root level item' do
548+
e = RailsParam::Param::InvalidParameterError.new('error')
549+
e.full_path_array = ["price"]
550+
expect(e.full_path).to eql "price"
551+
end
552+
553+
it 'has the correct full path for nested item' do
554+
e = RailsParam::Param::InvalidParameterError.new('error')
555+
e.full_path_array = ["hash", "hash2", "integers", 1]
556+
expect(e.full_path).to eql "hash[hash2][integers][1]"
557+
end
558+
end
480559
end
481560
end

0 commit comments

Comments
 (0)