Skip to content

Commit

Permalink
Allow to pass method name to :with option of rescue_from
Browse files Browse the repository at this point in the history
Closes #790
  • Loading branch information
namusyaka committed Jan 26, 2016
1 parent 5712b5b commit 30fb7c7
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* [#1243](https://github.com/ruby-grape/grape/pull/1243): Add `header` support for middleware - [@namusyaka](https://github.com/namusyaka).
* [#1252](https://github.com/ruby-grape/grape/pull/1252): Allow default to be a subset or equal to allowed values without raising IncompatibleOptionValues - [@jeradphelps](https://github.com/jeradphelps).
* [#1255](https://github.com/ruby-grape/grape/pull/1255): Allow param type definition in route_param - [@namusyaka](https://github.com/namusyaka)
* [#1257](https://github.com/ruby-grape/grape/pull/1257): Allow to pass method name to :with option of rescue_from - [@namusyaka](https://github.com/namusyaka)
* Your contribution here.

#### Fixes
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,22 @@ end

The `rescue_from` block must return a `Rack::Response` object, call `error!` or re-raise an exception.

The `with` keyword is available as `rescue_from` options, it can be passed method name or `Rack::Response` object.

```ruby
class Twitter::API < Grape::API
format :json
helpers do
def server_error!
error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' })
end
end

rescue_from :all, with: :server_error!
rescue_from ArgumentError, with: Rack::Response.new('rescued with a method', 400)
end
```

#### Unrescuable Exceptions

`Grape::Exceptions::InvalidVersionHeader`, which is raised when the version in the request header doesn't match the currently evaluated version for the endpoint, will _never_ be rescued from a `rescue_from` block (even a `rescue_from :all`) This is because Grape relies on Rack to catch that error and try the next versioned-route for cases where there exist identical Grape endpoints with different versions.
Expand Down
4 changes: 3 additions & 1 deletion lib/grape/dsl/request_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ def rescue_from(*args, &block)
end

options = args.extract_options!
handler ||= proc { options[:with] } if options.key?(:with)
if options.key?(:with) && !options[:with].instance_of?(Symbol)
handler ||= proc { options[:with] }
end

if args.include?(:all)
namespace_inheritable(:rescue_all, true)
Expand Down
4 changes: 4 additions & 0 deletions lib/grape/middleware/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def find_handler(klass)
handler = options[:rescue_handlers].find(-> { [] }) { |error, _| klass <= error }[1]
handler ||= options[:base_only_rescue_handlers][klass]
handler ||= options[:all_rescue_handler]
with_option = options[:rescue_options][:with]
if with_option.instance_of?(Symbol) && respond_to?(with_option)
handler ||= self.class.instance_method(with_option).bind(self)
end
handler
end

Expand Down
16 changes: 16 additions & 0 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,22 @@ def rescue_arg_error
end
end

describe '.rescue_from klass, with: :method_name' do
it 'rescues an error with the specified method name' do
subject.helpers do
def rescue_arg_error
error!('500 ArgumentError', 500)
end
end
subject.rescue_from ArgumentError, with: :rescue_arg_error
subject.get('/rescue_method') { fail ArgumentError }

get '/rescue_method'
expect(last_response.status).to eq(500)
expect(last_response.body).to eq('500 ArgumentError')
end
end

describe '.rescue_from klass, rescue_subclasses: boolean' do
before do
module ApiSpec
Expand Down

0 comments on commit 30fb7c7

Please sign in to comment.