Skip to content

Commit c20a9ad

Browse files
author
Sunny Juneja
committed
Add error! to rescue_from. Fixes #889.
1 parent f4da769 commit c20a9ad

File tree

7 files changed

+74
-13
lines changed

7 files changed

+74
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* [#952](https://github.com/intridea/grape/pull/952): Status method now raises error when called with invalid status code - [@dabrorius](https://github.com/dabrorius).
1414
* [#957](https://github.com/intridea/grape/pull/957): Regexp validator now supports `allow_blank`, `nil` value behavior changed - [@calfzhou](https://giihub.com/calfzhou).
1515
* [#962](https://github.com/intridea/grape/pull/962): The `default` attribute with `false` value is documented now - [@ajvondrak](https://github.com/ajvondrak).
16+
* [#974](https://github.com/intridea/grape/pull/974): Add error! to rescue_from blocks - [@whatasunnyday](https://github.com/whatasunnyday).
1617
* Your contribution here.
1718

1819
0.11.0 (2/23/2015)

README.md

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ You can rescue a `Grape::Exceptions::ValidationErrors` and respond with a custom
10311031
```ruby
10321032
format :json
10331033
subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
1034-
rack_response e.to_json, 400
1034+
error! e, 400
10351035
end
10361036
```
10371037

@@ -1442,17 +1442,29 @@ class Twitter::API < Grape::API
14421442
end
14431443
```
14441444

1445-
You can rescue all exceptions with a code block. The `error_response` wrapper
1445+
You can rescue all exceptions with a code block. The `error!` wrapper
14461446
automatically sets the default error code and content-type.
14471447

14481448
```ruby
14491449
class Twitter::API < Grape::API
14501450
rescue_from :all do |e|
1451-
error_response({ message: "rescued from #{e.class.name}" })
1451+
error!("rescued from #{e.class.name}")
14521452
end
14531453
end
14541454
```
14551455

1456+
Optionally, you can set the format, status code and headers.
1457+
1458+
```ruby
1459+
class Twitter::API < Grape::API
1460+
format :json
1461+
rescue_from :all do |e|
1462+
error!({ error: "Server error.", 500, { 'Content-Type' => 'text/error' } })
1463+
end
1464+
end
1465+
```
1466+
1467+
14561468
You can also rescue specific exceptions with a code block and handle the Rack
14571469
response at the lowest level.
14581470

@@ -1469,10 +1481,11 @@ Or rescue specific exceptions.
14691481
```ruby
14701482
class Twitter::API < Grape::API
14711483
rescue_from ArgumentError do |e|
1472-
Rack::Response.new([ "ArgumentError: #{e.message}" ], 500).finish
1484+
error!("ArgumentError: #{e.message}")
14731485
end
1486+
14741487
rescue_from NotImplementedError do |e|
1475-
Rack::Response.new([ "NotImplementedError: #{e.message}" ], 500).finish
1488+
error!("NotImplementedError: #{e.message}")
14761489
end
14771490
end
14781491
```
@@ -1492,10 +1505,10 @@ Then the following `rescue_from` clause will rescue exceptions of type `APIError
14921505

14931506
```ruby
14941507
rescue_from APIErrors::ParentError do |e|
1495-
Rack::Response.new({
1508+
error!({
14961509
error: "#{e.class} error",
14971510
message: e.message
1498-
}.to_json, e.status).finish
1511+
}, e.status)
14991512
end
15001513
```
15011514

@@ -1504,11 +1517,11 @@ The code below will rescue exceptions of type `RuntimeError` but _not_ its subcl
15041517

15051518
```ruby
15061519
rescue_from RuntimeError, rescue_subclasses: false do |e|
1507-
Rack::Response.new({
1520+
error!({
15081521
status: e.status,
15091522
message: e.message,
15101523
errors: e.errors
1511-
}.to_json, e.status).finish
1524+
}, e.status)
15121525
end
15131526
```
15141527

UPGRADING.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,47 @@ end
1515

1616
See [#957](https://github.com/intridea/grape/pull/957) for more information.
1717

18+
#### Replace error_response with error! in rescue_from blocks
19+
20+
Note: `error_response` is being deprecated, not removed.
21+
22+
```ruby
23+
def error!(message, status = options[:default_status], headers = {}, backtrace = [])
24+
headers = { 'Content-Type' => content_type }.merge(headers)
25+
rack_response(format_message(message, backtrace), status, headers)
26+
end
27+
```
28+
29+
For example,
30+
31+
```
32+
error_response({ message: { message: 'No such page.', id: 'missing_page' }, status: 404, headers: { 'Content-Type' => 'api/error' })
33+
```
34+
35+
becomes
36+
37+
```
38+
error!({ message: 'No such page.', id: 'missing_page' }, 404, { 'Content-Type' => 'api/error' })
39+
```
40+
41+
`error!` also supports just passing a message. `error!('Server error.')` and `format: :json` returns the following JSON response
42+
43+
```
44+
{ 'error': 'Server error. }
45+
```
46+
47+
with a status code of 500 and a Content Type of text/error.
48+
49+
Optionally, also replace `Rack::Response.new` with `error!.`
50+
The following are equivalent:
51+
52+
```
53+
Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish
54+
error!(e)
55+
```
56+
57+
See [#889](https://github.com/intridea/grape/issues/889) for more information.
58+
1859
### Upgrading to >= 0.11.0
1960

2061
#### Added Rack 1.6.0 support

lib/grape/error_formatter/json.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class << self
55
def call(message, backtrace, options = {}, env = nil)
66
message = Grape::ErrorFormatter::Base.present(message, env)
77

8-
result = message.is_a?(Hash) ? message : { error: message }
8+
result = message.is_a?(String) ? { error: message } : message
99
if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty?
1010
result = result.merge(backtrace: backtrace)
1111
end

lib/grape/exceptions/validation_errors.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def each
2424
end
2525
end
2626

27-
def as_json
27+
def as_json(_opts = {})
2828
errors.map do |k, v|
2929
{
3030
params: k,
@@ -33,7 +33,7 @@ def as_json
3333
end
3434
end
3535

36-
def to_json
36+
def to_json(_opts = {})
3737
as_json.to_json
3838
end
3939

lib/grape/middleware/error.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,16 @@ def exec_handler(e, &handler)
5858
end
5959
end
6060

61+
def error!(message, status = options[:default_status], headers = {}, backtrace = [])
62+
headers = { 'Content-Type' => content_type }.merge(headers)
63+
rack_response(format_message(message, backtrace), status, headers)
64+
end
65+
6166
def handle_error(e)
6267
error_response(message: e.message, backtrace: e.backtrace)
6368
end
6469

70+
# TODO: This method is deprecated. Refactor out.
6571
def error_response(error = {})
6672
status = error[:status] || options[:default_status]
6773
message = error[:message] || options[:default_message]

spec/grape/exceptions/validation_errors_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def app
2727
it 'can return structured json with separate fields' do
2828
subject.format :json
2929
subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
30-
rack_response e.to_json, 400
30+
error!(e, 400)
3131
end
3232
subject.params do
3333
optional :beer

0 commit comments

Comments
 (0)