Skip to content

Commit c6b72d8

Browse files
committed
Add CHANGELOG
Fix spec
1 parent 392dcca commit c6b72d8

File tree

5 files changed

+21
-47
lines changed

5 files changed

+21
-47
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [#2573](https://github.com/ruby-grape/grape/pull/2573): Clean up deprecated code - [@ericproulx](https://github.com/ericproulx).
77
* [#2575](https://github.com/ruby-grape/grape/pull/2575): Refactor Api description class - [@ericproulx](https://github.com/ericproulx).
88
* [#2577](https://github.com/ruby-grape/grape/pull/2577): Deprecate `return` in endpoint execution - [@ericproulx](https://github.com/ericproulx).
9+
* [#13](https://github.com/ericproulx/grape/pull/13): Refactor endpoint helpers and error middleware integration - [@ericproulx](https://github.com/ericproulx).
910
* Your contribution here.
1011

1112
#### Fixes

lib/grape/endpoint.rb

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,12 @@ class Endpoint
1111
include Grape::DSL::Headers
1212
include Grape::DSL::InsideRoute
1313

14-
attr_accessor :block, :source, :options
15-
attr_reader :env, :request
14+
attr_reader :env, :request, :source, :options
1615

1716
def_delegators :request, :params, :headers, :cookies
1817
def_delegator :cookies, :response_cookies
1918

2019
class << self
21-
def new(...)
22-
self == Endpoint ? Class.new(Endpoint).new(...) : super
23-
end
24-
2520
def before_each(new_setup = false, &block)
2621
@before_each ||= []
2722
if new_setup == false
@@ -82,17 +77,19 @@ def initialize(new_settings, options = {}, &block)
8277
@stream = nil
8378
@body = nil
8479

85-
return unless block
86-
87-
@source = block
88-
@block = lambda do |endpoint_instance|
89-
ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do
90-
endpoint_instance.instance_exec(&block)
91-
rescue LocalJumpError => e
92-
Grape.deprecator.warn 'Using `return` in an endpoint has been deprecated.'
93-
return e.exit_value
80+
if block
81+
@source = block
82+
@block = lambda do |endpoint_instance|
83+
ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do
84+
endpoint_instance.instance_exec(&block)
85+
rescue LocalJumpError => e
86+
Grape.deprecator.warn 'Using `return` in an endpoint has been deprecated.'
87+
return e.exit_value
88+
end
9489
end
9590
end
91+
92+
@helpers = build_helpers
9693
end
9794

9895
# Update our settings from a given set of stackable parameters. Used when
@@ -194,6 +191,8 @@ def call(env)
194191
def call!(env)
195192
env[Grape::Env::API_ENDPOINT] = self
196193
@env = env
194+
# this adds the helpers only to the instance
195+
singleton_class.include(@helpers) if @helpers
197196
@app.call(env)
198197
end
199198

@@ -259,19 +258,13 @@ def execute
259258
@block&.call(self)
260259
end
261260

262-
def helpers
263-
lazy_initialize! && @helpers
264-
end
265-
266261
def lazy_initialize!
267262
return true if @lazy_initialized
268263

269264
@lazy_initialize_lock.synchronize do
270265
return true if @lazy_initialized
271266

272-
@helpers = build_helpers&.tap { |mod| self.class.include mod }
273-
@app = options[:app] || build_stack(@helpers)
274-
267+
@app = options[:app] || build_stack
275268
@lazy_initialized = true
276269
end
277270
end
@@ -323,16 +316,15 @@ def options?
323316

324317
private
325318

326-
def build_stack(helpers)
319+
def build_stack
327320
stack = Grape::Middleware::Stack.new
328321

329322
content_types = namespace_stackable_with_hash(:content_types)
330323
format = namespace_inheritable(:format)
331324

332325
stack.use Rack::Head
333326
stack.use Rack::Lint if lint?
334-
stack.use Class.new(Grape::Middleware::Error),
335-
helpers: helpers,
327+
stack.use Grape::Middleware::Error,
336328
format: format,
337329
content_types: content_types,
338330
default_status: namespace_inheritable(:default_error_status),

lib/grape/middleware/error.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ class Error < Base
1616
}.freeze
1717
}.freeze
1818

19-
def initialize(app, **options)
20-
super
21-
self.class.include(options[:helpers]) if options[:helpers]
22-
end
23-
2419
def call!(env)
2520
@env = env
2621
error_response(catch(:error) { return @app.call(@env) })
@@ -103,12 +98,7 @@ def rescue_handler_for_any_class(klass)
10398
end
10499

105100
def run_rescue_handler(handler, error, endpoint)
106-
if handler.instance_of?(Symbol)
107-
raise NoMethodError, "undefined method '#{handler}'" unless respond_to?(handler)
108-
109-
handler = public_method(handler)
110-
end
111-
101+
handler = endpoint.public_method(handler) if handler.instance_of?(Symbol)
112102
response = catch(:error) do
113103
handler.arity.zero? ? endpoint.instance_exec(&handler) : endpoint.instance_exec(error, &handler)
114104
end

spec/grape/api_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2369,7 +2369,7 @@ def rescue_no_method_error
23692369
subject.rescue_from :all, with: :not_exist_method
23702370
subject.get('/rescue_method') { raise StandardError }
23712371

2372-
expect { get '/rescue_method' }.to raise_error(NoMethodError, /^undefined method 'not_exist_method'/)
2372+
expect { get '/rescue_method' }.to raise_error(NameError, /^undefined method [`']not_exist_method'/)
23732373
end
23742374

23752375
it 'correctly chooses exception handler if :all handler is specified' do

spec/grape/endpoint_spec.rb

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -735,18 +735,9 @@ def handle_argument_error
735735

736736
describe 'NameError' do
737737
context 'when referencing an undefined local variable or method' do
738-
let(:error_message) do
739-
if Gem::Version.new(RUBY_VERSION).release <= Gem::Version.new('3.2')
740-
%r{undefined local variable or method `undefined_helper' for #<Class:0x[0-9a-fA-F]+> in '/hey' endpoint}
741-
else
742-
opening_quote = Gem::Version.new(RUBY_VERSION).release >= Gem::Version.new('3.4') ? "'" : '`'
743-
/undefined local variable or method #{opening_quote}undefined_helper' for/
744-
end
745-
end
746-
747738
it 'raises NameError but stripping the internals of the Grape::Endpoint class and including the API route' do
748739
subject.get('/hey') { undefined_helper }
749-
expect { get '/hey' }.to raise_error(NameError, error_message)
740+
expect { get '/hey' }.to raise_error(NameError, /^undefined local variable or method ['`]undefined_helper' for/)
750741
end
751742
end
752743
end

0 commit comments

Comments
 (0)