Repository navigation
Conversation
…gate Since ruby-grape#2703, Grape redispatches an exception raised inside a rescue_from block, so it no longer reaches Rack middleware mounted above Grape. That fixed ruby-grape#2482, and it also stopped a block from handing an exception to such middleware by re-raising it. Active Record's DatabaseSelector with a custom resolver that retries a request on the primary after an ActiveRecord::ReadOnlyError is one: an API that re-raised the error from rescue_from :all for it now answers 500 where the request used to recover. Grape.config.raise_rescue_handler_errors brings back the earlier behaviour, as raise_rendering_errors (ruby-grape#2840) does for rendering failures. With it on, whatever a rescue_from block raises is re-raised untouched. A block that calls error! still renders, because Halt is rescued ahead of it. Off by default. Fixes ruby-grape#3003.
dduugg
force-pushed
the
raise-rescue-handler-errors
branch
from
October 22, 2026 00:57
17ea474 to
7ce8f36
Compare
Danger ReportNo issues found. |
Member
|
I fixed danger-changelog in 0.10.1, dblock/danger-changelog#85 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since #2703 (3.3.0), an exception raised inside a
rescue_fromblock is redispatched, so it never reaches Rack middleware mounted above Grape, and there is no opt-out. In #3003 that middleware is Active Record'sDatabaseSelectorwith a custom resolver that retries a request on the primary after anActiveRecord::ReadOnlyError. The app re-raised the error fromrescue_from :allfor it, and on 3.3 and later the request answers 500 where it used to recover.What
This adds
Grape.config.raise_rescue_handler_errors, off by default, as @dblock sketched in #3003. With it on, therescue StandardErrorinrun_rescue_handlerre-raises the exception untouched and skipsredispatch. A block that callserror!still renders, because theHaltit raises is rescued first.It is the handler-side counterpart of
raise_rendering_errors(#2840) and is wired the same way: a setting beside it inlib/grape.rb, a bullet in the README's Configuration list, and the opt-out documented in the README section it opts out of.With the setting on, a raising handler behaves as it did on 3.2.1. The table shows what a route that raises gets when
rescue_from :alldoes each of these:raise eWrapped, which has its ownrescue_fromWrappedWrappedhandlerWrappedGrape::Exceptions::Basewith: :methodthat raiseserror!(..., 422)Why a global setting
#3003 also discussed
rescue_from ActiveRecord::ReadOnlyError, propagate: true. Grape picks a handler frome.class, sopropagate:would miss aReadOnlyErrorthat arrives as another exception'scause, which the resolver in #3003 also retries (comment). This PR leavespropagate:out. It can follow separately if you want both.Notes
rescue_from :internal_grape_exceptionsnever sees a handler's exception, and neitherrack.exceptionnorgrape.exceptionis set. The README says so.error_response,default_rescue_handler) run throughrun_rescue_handlertoo, so with the setting on an unexpected exception from one of them also propagates, as on 3.2.1. A rendering failure is still answered by the failsafe unlessraise_rendering_errorsis on.Tests
Three examples in
spec/grape/middleware/error_spec.rb, under "when a rescue_from block raises":rescue_from :internal_grape_exceptionsand leaves both env keys unset (the Let arescue_fromhandler propagate an exception instead of rendering it #3003 case);rescue_fromis registered for its class;error!still renders.Without the
lib/change the first two fail. Moving the setting check ahead of theHaltrescue fails the third.Fixes #3003.