From 5bf1744432d84d452cf62e5240d0bb3b7c56747f Mon Sep 17 00:00:00 2001 From: Juan Carlos Garcia Date: Thu, 9 Nov 2023 23:30:27 +0100 Subject: [PATCH 1/3] fix(#2236): Stripping the internals of `Grape::Endpoint` when `NoMethodError` is raised --- CHANGELOG.md | 1 + lib/grape/endpoint.rb | 4 ++++ spec/grape/endpoint_spec.rb | 11 +++++++++++ 3 files changed, 16 insertions(+) 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..a25aa298ff 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -403,5 +403,9 @@ 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}") + end end end diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 8cdcc1cffe..e3de82a7a0 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -692,6 +692,17 @@ def app end end + describe '#method_missing' do + it 'raises NoMethodError but stripping the internals of the Grape::Endpoint class' do + subject.get('/hey') do + undefined_helper + end + expect { + get '/hey' + }.to raise_error(NoMethodError, /^undefined method `undefined_helper` for #$/) + end + end + it 'does not persist params between calls' do subject.post('/new') do params[:text] From 805228c955a979e3e70045cbd8d0bf0db3bf7663 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garcia Date: Fri, 10 Nov 2023 09:55:15 +0100 Subject: [PATCH 2/3] fix(#2236): Follow quote ruby style and including the endpoint in the error message --- lib/grape/endpoint.rb | 2 +- spec/grape/endpoint_spec.rb | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index a25aa298ff..04deef72aa 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -405,7 +405,7 @@ def options? end def method_missing(name, *args) - raise NoMethodError.new("undefined method `#{name}` for #{self.class}") + raise NoMethodError.new("undefined method `#{name}' for #{self.class} in `#{self.route.origin}' endpoint") end end end diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index e3de82a7a0..26f5af0fc5 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -693,13 +693,26 @@ def app end describe '#method_missing' do - it 'raises NoMethodError but stripping the internals of the Grape::Endpoint class' do - subject.get('/hey') do - undefined_helper + 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 { + get '/hey' + }.to raise_error(NoMethodError, /^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 { + get '/hey' + }.to raise_error(NoMethodError, /^undefined method `x' for #$/) end - expect { - get '/hey' - }.to raise_error(NoMethodError, /^undefined method `undefined_helper` for #$/) end end From 27c26e953f1a4263fcea2cf6b57c9a6e88318164 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garcia Date: Fri, 10 Nov 2023 10:06:54 +0100 Subject: [PATCH 3/3] fix(#2236): Running rubocop and applying corrections --- lib/grape/endpoint.rb | 8 ++++++-- spec/grape/endpoint_spec.rb | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 04deef72aa..f50084270e 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -404,8 +404,12 @@ def options? 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 `#{self.route.origin}' endpoint") + 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 26f5af0fc5..5788bd9131 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -698,9 +698,9 @@ def app subject.get('/hey') do undefined_helper end - expect { + expect do get '/hey' - }.to raise_error(NoMethodError, /^undefined method `undefined_helper' for # in `\/hey' endpoint/) + end.to raise_error(NoMethodError, %r{^undefined method `undefined_helper' for # in `/hey' endpoint}) end end @@ -709,9 +709,9 @@ def app subject.get('/hey') do Object.new.x end - expect { + expect do get '/hey' - }.to raise_error(NoMethodError, /^undefined method `x' for #$/) + end.to raise_error(NoMethodError, /^undefined method `x' for #$/) end end end