Skip to content

Commit

Permalink
Add error! to rescue_from. Fixes ruby-grape#889.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sunny Juneja committed Apr 1, 2015
1 parent f4da769 commit c20a9ad
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* [#952](https://github.com/intridea/grape/pull/952): Status method now raises error when called with invalid status code - [@dabrorius](https://github.com/dabrorius).
* [#957](https://github.com/intridea/grape/pull/957): Regexp validator now supports `allow_blank`, `nil` value behavior changed - [@calfzhou](https://giihub.com/calfzhou).
* [#962](https://github.com/intridea/grape/pull/962): The `default` attribute with `false` value is documented now - [@ajvondrak](https://github.com/ajvondrak).
* [#974](https://github.com/intridea/grape/pull/974): Add error! to rescue_from blocks - [@whatasunnyday](https://github.com/whatasunnyday).
* Your contribution here.

0.11.0 (2/23/2015)
Expand Down
31 changes: 22 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ You can rescue a `Grape::Exceptions::ValidationErrors` and respond with a custom
```ruby
format :json
subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
rack_response e.to_json, 400
error! e, 400
end
```

Expand Down Expand Up @@ -1442,17 +1442,29 @@ class Twitter::API < Grape::API
end
```

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

```ruby
class Twitter::API < Grape::API
rescue_from :all do |e|
error_response({ message: "rescued from #{e.class.name}" })
error!("rescued from #{e.class.name}")
end
end
```

Optionally, you can set the format, status code and headers.

```ruby
class Twitter::API < Grape::API
format :json
rescue_from :all do |e|
error!({ error: "Server error.", 500, { 'Content-Type' => 'text/error' } })
end
end
```


You can also rescue specific exceptions with a code block and handle the Rack
response at the lowest level.

Expand All @@ -1469,10 +1481,11 @@ Or rescue specific exceptions.
```ruby
class Twitter::API < Grape::API
rescue_from ArgumentError do |e|
Rack::Response.new([ "ArgumentError: #{e.message}" ], 500).finish
error!("ArgumentError: #{e.message}")
end

rescue_from NotImplementedError do |e|
Rack::Response.new([ "NotImplementedError: #{e.message}" ], 500).finish
error!("NotImplementedError: #{e.message}")
end
end
```
Expand All @@ -1492,10 +1505,10 @@ Then the following `rescue_from` clause will rescue exceptions of type `APIError

```ruby
rescue_from APIErrors::ParentError do |e|
Rack::Response.new({
error!({
error: "#{e.class} error",
message: e.message
}.to_json, e.status).finish
}, e.status)
end
```

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

```ruby
rescue_from RuntimeError, rescue_subclasses: false do |e|
Rack::Response.new({
error!({
status: e.status,
message: e.message,
errors: e.errors
}.to_json, e.status).finish
}, e.status)
end
```

Expand Down
41 changes: 41 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,47 @@ end

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

#### Replace error_response with error! in rescue_from blocks

Note: `error_response` is being deprecated, not removed.

```ruby
def error!(message, status = options[:default_status], headers = {}, backtrace = [])
headers = { 'Content-Type' => content_type }.merge(headers)
rack_response(format_message(message, backtrace), status, headers)
end
```

For example,

```
error_response({ message: { message: 'No such page.', id: 'missing_page' }, status: 404, headers: { 'Content-Type' => 'api/error' })
```

becomes

```
error!({ message: 'No such page.', id: 'missing_page' }, 404, { 'Content-Type' => 'api/error' })
```

`error!` also supports just passing a message. `error!('Server error.')` and `format: :json` returns the following JSON response

```
{ 'error': 'Server error. }
```

with a status code of 500 and a Content Type of text/error.

Optionally, also replace `Rack::Response.new` with `error!.`
The following are equivalent:

```
Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish
error!(e)
```

See [#889](https://github.com/intridea/grape/issues/889) for more information.

### Upgrading to >= 0.11.0

#### Added Rack 1.6.0 support
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/error_formatter/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class << self
def call(message, backtrace, options = {}, env = nil)
message = Grape::ErrorFormatter::Base.present(message, env)

result = message.is_a?(Hash) ? message : { error: message }
result = message.is_a?(String) ? { error: message } : message
if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty?
result = result.merge(backtrace: backtrace)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/grape/exceptions/validation_errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def each
end
end

def as_json
def as_json(_opts = {})
errors.map do |k, v|
{
params: k,
Expand All @@ -33,7 +33,7 @@ def as_json
end
end

def to_json
def to_json(_opts = {})
as_json.to_json
end

Expand Down
6 changes: 6 additions & 0 deletions lib/grape/middleware/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,16 @@ def exec_handler(e, &handler)
end
end

def error!(message, status = options[:default_status], headers = {}, backtrace = [])
headers = { 'Content-Type' => content_type }.merge(headers)
rack_response(format_message(message, backtrace), status, headers)
end

def handle_error(e)
error_response(message: e.message, backtrace: e.backtrace)
end

# TODO: This method is deprecated. Refactor out.
def error_response(error = {})
status = error[:status] || options[:default_status]
message = error[:message] || options[:default_message]
Expand Down
2 changes: 1 addition & 1 deletion spec/grape/exceptions/validation_errors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def app
it 'can return structured json with separate fields' do
subject.format :json
subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
rack_response e.to_json, 400
error!(e, 400)
end
subject.params do
optional :beer
Expand Down

0 comments on commit c20a9ad

Please sign in to comment.