Skip to content

Commit

Permalink
adding option to allow grape to handle Grape::Exception when rescue :…
Browse files Browse the repository at this point in the history
…all is set
  • Loading branch information
Mason McLead committed May 13, 2016
1 parent a711cab commit 6f0cffe
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
0.16.3 (Next)
=============

* Your contribution here.
* [#1398](https://github.com/ruby-grape/grape/pull/1398): Option to allow Grape to handle Grape::Exception when rescue :all is set [@mmclead](https://github.com/mmclead)

#### Features

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,14 @@ class Twitter::API < Grape::API
end
```

As an option to ```rescue_from :all``` you can specify that Grape should still use its built in exception handling.

```ruby
class Twitter::API < Grape::API
rescue_from :all, rescue_grape_errors: true
end
```

You can also rescue specific exceptions.

```ruby
Expand Down
9 changes: 7 additions & 2 deletions lib/grape/middleware/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def default_options
error_formatters: {},
rescue_all: false, # true to rescue all exceptions
rescue_subclasses: true, # rescue subclasses of exceptions listed
rescue_options: { backtrace: false }, # true to display backtrace
rescue_options: { backtrace: false, rescue_grape_errors: false }, # true to display backtrace, true to let Grape handle Grape::Exceptions
rescue_handlers: {}, # rescue handler blocks
base_only_rescue_handlers: {}, # rescue handler blocks rescuing only the base class
all_rescue_handler: nil # rescue handler block to rescue from all exceptions
Expand All @@ -30,7 +30,7 @@ def call!(env)
end)
rescue StandardError => e
is_rescuable = rescuable?(e.class)
if e.is_a?(Grape::Exceptions::Base) && !is_rescuable
if e.is_a?(Grape::Exceptions::Base) && (!is_rescuable || rescuable_by_grape?(e.class))
handler = ->(arg) { error_response(arg) }
else
raise unless is_rescuable
Expand Down Expand Up @@ -59,6 +59,11 @@ def rescuable?(klass)
options[:rescue_all] || (options[:rescue_handlers] || []).any? { |error, _handler| klass <= error } || (options[:base_only_rescue_handlers] || []).include?(klass)
end

def rescuable_by_grape?(klass)
return false if klass == Grape::Exceptions::InvalidVersionHeader
options[:rescue_options][:rescue_grape_errors]
end

def exec_handler(e, &handler)
if handler.lambda? && handler.arity == 0
instance_exec(&handler)
Expand Down
22 changes: 22 additions & 0 deletions spec/grape/exceptions/body_parse_errors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@ def app
expect(last_response.body).to eq('message was processed')
end
end

context 'and rescue_grape_errors set to true' do
before do
subject.rescue_from :all, rescue_grape_errors: true
end

context 'with content_type json' do
it 'returns body parsing error message' do
post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
expect(last_response.status).to eq 400
expect(last_response.body).to include 'message body does not match declared format'
end
end

context 'with content_type xml' do
it 'returns body parsing error message' do
post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
expect(last_response.status).to eq 400
expect(last_response.body).to include 'message body does not match declared format'
end
end
end
end

context 'api without a rescue handler' do
Expand Down

0 comments on commit 6f0cffe

Please sign in to comment.