diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a358f996e..504211ef34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Your contribution here. * [#1737](https://github.com/ruby-grape/grape/pull/1737): Fix translating error when passing symbols as params in custom validations - [@mlzhuyi](https://github.com/mlzhuyi). +* []: Rescue truly all exceptions - [@mtsmfm](https://github.com/mtsmfm). ### 1.0.2 (1/10/2018) diff --git a/README.md b/README.md index 9e70ddd8c1..eeb32629fa 100644 --- a/README.md +++ b/README.md @@ -2071,7 +2071,7 @@ literally accepts every request. ## Exception Handling -Grape can be told to rescue all `StandardError` exceptions and return them in the API format. +Grape can be told to rescue all exceptions and return them in the API format. ```ruby class Twitter::API < Grape::API @@ -2098,7 +2098,7 @@ class Twitter::API < Grape::API end ``` -In this case ```UserDefinedError``` must be inherited from ```StandardError```. +```UserDefinedError``` can be inherited from any exception class. Notice that you could combine these two approaches (rescuing custom errors takes precedence). For example, it's useful for handling all exceptions except Grape validation errors. diff --git a/lib/grape/middleware/error.rb b/lib/grape/middleware/error.rb index 3c00786bfd..52418e6ab0 100644 --- a/lib/grape/middleware/error.rb +++ b/lib/grape/middleware/error.rb @@ -36,7 +36,7 @@ def call!(env) error_response(catch(:error) do return @app.call(@env) end) - rescue StandardError => e + rescue Exception => e # rubocop:disable Lint/RescueException is_rescuable = rescuable?(e.class) if e.is_a?(Grape::Exceptions::Base) && (!is_rescuable || rescuable_by_grape?(e.class)) handler = ->(arg) { error_response(arg) } diff --git a/spec/grape/middleware/exception_spec.rb b/spec/grape/middleware/exception_spec.rb index e6bb44597b..ba3752fce7 100644 --- a/spec/grape/middleware/exception_spec.rb +++ b/spec/grape/middleware/exception_spec.rb @@ -103,8 +103,13 @@ def app run ExceptionSpec::OtherExceptionApp end end - it 'does not trap errors other than StandardError' do - expect { get '/' }.to raise_error(NotImplementedError, 'snow!') + it 'sets the message appropriately' do + get '/' + expect(last_response.body).to eq('snow!') + end + it 'defaults to a 500 status' do + get '/' + expect(last_response.status).to eq(500) end end end