Skip to content

Commit 37b7c47

Browse files
jlfaberdblock
authored andcommitted
Rescue StandardError from explicit values validator procs (#1679)
* Rescue StandardError from explicit values validator procs * Update CHANGELOG.md * Update CHANGELOG.md * Code Review feedback * Code Review feedback
1 parent af45b1d commit 37b7c47

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
* [#1652](https://github.com/ruby-grape/grape/pull/1652): Fix missing backtrace that was not being bubbled up to the `error_formatter` - [@dcsg](https://github.com/dcsg).
1313
* [#1661](https://github.com/ruby-grape/grape/pull/1661): Handle deeply-nested dependencies correctly - [@rnubel](https://github.com/rnubel), [@jnardone](https://github.com/jnardone).
14+
* [#1679](https://github.com/ruby-grape/grape/pull/1679): Treat StandardError from explicit values validator proc as false - [@jlfaber](https://github.com/jlfaber).
1415

1516
### 1.0.0 (7/3/2017)
1617

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,8 @@ end
11791179

11801180
Alternatively, a Proc with arity one (i.e. taking one argument) can be used to explicitly validate
11811181
each parameter value. In that case, the Proc is expected to return a truthy value if the parameter
1182-
value is valid.
1182+
value is valid. The parameter will be considered invalid if the Proc returns a falsy value or if it
1183+
raises a StandardError.
11831184

11841185
```ruby
11851186
params do

lib/grape/validations/validators/values.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,23 @@ def validate_param!(attr_name, params)
3232
unless check_excepts(param_array)
3333

3434
raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \
35-
unless check_values(param_array)
35+
unless check_values(param_array, attr_name)
3636

3737
raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \
3838
if @proc && !param_array.all? { |param| @proc.call(param) }
3939
end
4040

4141
private
4242

43-
def check_values(param_array)
43+
def check_values(param_array, attr_name)
4444
values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
4545
return true if values.nil?
46-
return param_array.all? { |param| values.call(param) } if values.is_a? Proc
46+
begin
47+
return param_array.all? { |param| values.call(param) } if values.is_a? Proc
48+
rescue StandardError => e
49+
warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
50+
return false
51+
end
4752
param_array.all? { |param| values.include?(param) }
4853
end
4954

spec/grape/validations/validators/values_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ class API < Grape::API
110110
{ type: params[:type] }
111111
end
112112

113+
params do
114+
requires :number, type: Integer, values: ->(v) { v > 0 }
115+
end
116+
get '/lambda_int_val' do
117+
{ number: params[:number] }
118+
end
119+
113120
params do
114121
requires :type, values: -> { [] }
115122
end
@@ -357,6 +364,24 @@ def app
357364
expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
358365
end
359366

367+
it 'does not allow non-numeric string value for int value using lambda' do
368+
get('/lambda_int_val', number: 'foo')
369+
expect(last_response.status).to eq 400
370+
expect(last_response.body).to eq({ error: 'number is invalid, number does not have a valid value' }.to_json)
371+
end
372+
373+
it 'does not allow nil for int value using lambda' do
374+
get('/lambda_int_val', number: nil)
375+
expect(last_response.status).to eq 400
376+
expect(last_response.body).to eq({ error: 'number does not have a valid value' }.to_json)
377+
end
378+
379+
it 'allows numeric string for int value using lambda' do
380+
get('/lambda_int_val', number: '3')
381+
expect(last_response.status).to eq 200
382+
expect(last_response.body).to eq({ number: 3 }.to_json)
383+
end
384+
360385
it 'allows value using lambda' do
361386
get('/lambda_val', type: 'valid-type1')
362387
expect(last_response.status).to eq 200

0 commit comments

Comments
 (0)