Skip to content

Commit 7b68383

Browse files
committed
Allow rescue from non-StandardError exceptions
ref ruby-grape#1745 ruby-grape#1713
1 parent 18c9d4b commit 7b68383

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
#### Fixes
88

99
* [#1740](https://github.com/ruby-grape/grape/pull/1740): Fix dependent parameter validation using `given` when parameter is a `Hash` - [@jvortmann](https://github.com/jvortmann).
10-
11-
* Your contribution here.
1210
* [#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).
11+
* [#1749](https://github.com/ruby-grape/grape/pull/1749): Allow rescue from non-`StandardError` errors - [@dm1try](https://github.com/dm1try).
12+
* Your contribution here.
1313

1414
### 1.0.2 (1/10/2018)
1515

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
- [Exception Handling](#exception-handling)
7979
- [Rescuing exceptions inside namespaces](#rescuing-exceptions-inside-namespaces)
8080
- [Unrescuable Exceptions](#unrescuable-exceptions)
81+
- [Exceptions that should be rescued explicitly](#exceptions-that-should-be-rescued-explicitly)
8182
- [Rails 3.x](#rails-3x)
8283
- [Logging](#logging)
8384
- [API Formats](#api-formats)
@@ -2079,6 +2080,9 @@ class Twitter::API < Grape::API
20792080
end
20802081
```
20812082

2083+
This mimics [default `rescue` behaviour](https://ruby-doc.org/core/StandardError.html) when an exception type is not provided.
2084+
Any other exception should be rescued explicitly, see [below](#exceptions-that-should-be-rescued-explicitly).
2085+
20822086
Grape can also rescue from all exceptions and still use the built-in exception handing.
20832087
This will give the same behavior as `rescue_from :all` with the addition that Grape will use the exception handling defined by all Exception classes that inherit `Grape::Exceptions::Base`.
20842088

@@ -2281,6 +2285,12 @@ Here `'inner'` will be result of handling occured `ArgumentError`.
22812285

22822286
`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.
22832287

2288+
#### Exceptions that should be rescued explicitly
2289+
2290+
Any exception that is not subclass of `StandardError` should be rescued explicitly.
2291+
Usually it is not a case for an application logic as such errors point to problems in Ruby runtime.
2292+
This is following [standard recomendations for exceptions handling](https://ruby-doc.org/core/Exception.html)
2293+
22842294
### Rails 3.x
22852295

22862296
When mounted inside containers, such as Rails 3.x, errors such as "404 Not Found" or

lib/grape/middleware/error.rb

+8
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ def call!(env)
4646
end
4747

4848
handler.nil? ? handle_error(e) : exec_handler(e, &handler)
49+
rescue Exception => e # rubocop:disable Lint/RescueException
50+
handler = options[:rescue_handlers].find do |error_class, error_handler|
51+
break error_handler if e.class <= error_class
52+
end
53+
54+
raise unless handler
55+
56+
exec_handler(e, &handler)
4957
end
5058
end
5159

spec/grape/middleware/exception_spec.rb

+13
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ def app
109109
end
110110
end
111111

112+
context 'Non-StandardError exception with a provided rescue handler' do
113+
subject do
114+
Rack::Builder.app do
115+
use Spec::Support::EndpointFaker
116+
use Grape::Middleware::Error, rescue_handlers: { NotImplementedError => -> { [200, {}, 'rescued'] } }
117+
run ExceptionSpec::OtherExceptionApp
118+
end
119+
end
120+
it 'rescues the exception using the provided handler' do
121+
get '/'
122+
expect(last_response.body).to eq('rescued')
123+
end
124+
end
112125
context do
113126
subject do
114127
Rack::Builder.app do

0 commit comments

Comments
 (0)