Skip to content

Commit 06cdf05

Browse files
committed
Call #after of middleware on error
Add a test for the bevhavior of returning Rack response by after callback
1 parent 87cd364 commit 06cdf05

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [#1227](https://github.com/ruby-grape/grape/pull/1227): Store `message_key` on Grape::Exceptions::Validation - [@stjhimy](https://github.com/sthimy).
77
* [#1232](https://github.com/ruby-grape/grape/pull/1232): Helpers are now available inside `rescue_from` - [@namusyaka](https://github.com/namusyaka).
88
* [#1237](https://github.com/ruby-grape/grape/pull/1237): Allow multiple parameters in `given`, which behaves as if the scopes were nested in the inputted order - [@ochagata](https://github.com/ochagata).
9+
* [#1238](https://github.com/ruby-grape/grape/pull/1238): Call `after` of middleware on error - [@namusyaka](https://github.com/namusyaka).
910
* Your contribution here.
1011

1112
#### Fixes

UPGRADING.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@ Upgrading Grape
33

44
### Upgrading to >= 0.14.0
55

6+
#### Changes to behavior of `after` method of middleware on error
7+
8+
The `after` method of the middleware is now called on error.
9+
The following code would work correctly.
10+
11+
```ruby
12+
class CustomMiddleware < Grape::Middleware::Base
13+
def after
14+
puts "Yay!"
15+
end
16+
end
17+
18+
class API < Grape::API
19+
use CustomMiddleware
20+
21+
get { raise StandardError }
22+
end
23+
24+
mock = Rack::MockRequest.env_for(?/)
25+
API.new.call(mock) #=. Displaying the message correctly.
26+
```
27+
28+
See #1147 and #1240 for discussion of the issues.
29+
630
#### Changes to availability of DSL methods in filters
731

832
The `#declared` method of the route DSL is no longer available in the `before` filter. Using `declared` in a `before` filter will now raise `Grape::DSL::InsideRoute::MethodNotYetAvailable`.

lib/grape/middleware/base.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ def call(env)
2222
def call!(env)
2323
@env = env
2424
before
25-
@app_response = @app.call(@env)
26-
after || @app_response
25+
begin
26+
@app_response = @app.call(@env)
27+
ensure
28+
after_response = after
29+
end
30+
after_response || @app_response
2731
end
2832

2933
# @abstract

lib/grape/middleware/formatter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def before
1919
end
2020

2121
def after
22+
return unless @app_response
2223
status, headers, bodies = *@app_response
2324

2425
if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status)

spec/grape/middleware/base_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@
2929
after { subject.call!({}) }
3030
end
3131

32+
context 'callbacks on error' do
33+
let(:blank_app) { ->(_) { fail StandardError } }
34+
35+
it 'calls #after' do
36+
expect(subject).to receive(:after)
37+
expect { subject.call({}) }.to raise_error(StandardError)
38+
end
39+
end
40+
41+
context 'after callback' do
42+
before do
43+
allow(subject).to receive(:after).and_return([200, {}, 'Hello from after callback'])
44+
end
45+
46+
it 'overwrites application response' do
47+
expect(subject.call!({}).last).to eq('Hello from after callback')
48+
end
49+
end
50+
3251
it 'is able to access the response' do
3352
subject.call({})
3453
expect(subject.response).to be_kind_of(Rack::Response)

0 commit comments

Comments
 (0)