Skip to content

Commit 76c900a

Browse files
committed
Merge pull request #1240 from namusyaka/call-after-block-on-error
Call #after of middleware on error
2 parents b56534c + cc60281 commit 76c900a

File tree

6 files changed

+74
-2
lines changed

6 files changed

+74
-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

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
- [Before and After](#before-and-after)
7474
- [Anchoring](#anchoring)
7575
- [Using Custom Middleware](#using-custom-middleware)
76+
- [Grape Middleware](#grape-middleware)
7677
- [Rails Middleware](#rails-middleware)
7778
- [Remote IP](#remote-ip)
7879
- [Writing Tests](#writing-tests)
@@ -2557,6 +2558,33 @@ part.
25572558

25582559
## Using Custom Middleware
25592560

2561+
### Grape Middleware
2562+
2563+
You can make a custom middleware by using `Grape::Middleware::Base`.
2564+
It's inherited from some grape official middlewares in fact.
2565+
2566+
For example, you can write a middleware to log application exception.
2567+
2568+
```ruby
2569+
class LoggingError < Grape::Middleware::Base
2570+
def after
2571+
if @api_response[0] == 500
2572+
env['rack.logger'].error("Raised error on #{env['PATH_INFO']}")
2573+
end
2574+
end
2575+
end
2576+
```
2577+
2578+
Your middleware can overwrite application response as follows, except error case.
2579+
2580+
```ruby
2581+
class Overwriter < Grape::Middleware::Base
2582+
def after
2583+
[200, { 'Content-Type' => 'text/plain' }, ['Overwrited.']]
2584+
end
2585+
end
2586+
```
2587+
25602588
### Rails Middleware
25612589

25622590
Note that when you're using Grape mounted on Rails you don't have to use Rails middleware because it's already included into your middleware stack.

UPGRADING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
Upgrading Grape
22
===============
33

4+
### Upgrading to >= 0.15.0
5+
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 ErrorMiddleware < Grape::Middleware::Base
13+
def after
14+
if @api_response[0] == 500
15+
env['rack.logger'].debug("Raised error on #{env['PATH_INFO']}")
16+
end
17+
end
18+
end
19+
```
20+
21+
See [#1147](https://github.com/ruby-grape/grape/issues/1147) and [#1240](https://github.com/ruby-grape/grape/issues/1240) for discussion of the issues.
22+
423
### Upgrading to >= 0.14.0
524

625
#### Changes to availability of DSL methods in filters

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)