diff --git a/CHANGELOG.md b/CHANGELOG.md index d17ce560c2..e19d4928ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * [#2364](https://github.com/ruby-grape/grape/pull/2364): Add missing requires - [@ericproulx](https://github.com/ericproulx). * [#2366](https://github.com/ruby-grape/grape/pull/2366): Default quality to 1.0 in the `Accept` header when omitted - [@hiddewie](https://github.com/hiddewie). +* [#2368](https://github.com/ruby-grape/grape/pull/2368): Stripping the internals of `Grape::Endpoint` when `NoMethodError` is raised - [@jcagarcia](https://github.com/jcagarcia). * Your contribution here. ### 1.8.0 (2023/08/30) diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 663a3e8f1d..f50084270e 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -403,5 +403,13 @@ def options? options[:options_route_enabled] && env[Grape::Http::Headers::REQUEST_METHOD] == Grape::Http::Headers::OPTIONS end + + def method_missing(name, *_args) + raise NoMethodError.new("undefined method `#{name}' for #{self.class} in `#{route.origin}' endpoint") + end + + def respond_to_missing?(method_name, include_private = false) + super + end end end diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 8cdcc1cffe..5788bd9131 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -692,6 +692,30 @@ def app end end + describe '#method_missing' do + context 'when referencing an undefined local variable' do + it 'raises NoMethodError but stripping the internals of the Grape::Endpoint class and including the API route' do + subject.get('/hey') do + undefined_helper + end + expect do + get '/hey' + end.to raise_error(NoMethodError, %r{^undefined method `undefined_helper' for # in `/hey' endpoint}) + end + end + + context 'when performing an undefined method of an instance inside the API' do + it 'raises NoMethodError but stripping the internals of the Object class' do + subject.get('/hey') do + Object.new.x + end + expect do + get '/hey' + end.to raise_error(NoMethodError, /^undefined method `x' for #$/) + end + end + end + it 'does not persist params between calls' do subject.post('/new') do params[:text]