Skip to content

Fix non-local returns inside transaction blocks (silent rollback on Rails 7.0/7.1) - #32

Open
TalGruperFolloze wants to merge 1 commit into
rameerez:mainfrom
TalGruperFolloze:fix-transaction-exit-statements
Open

Fix non-local returns inside transaction blocks (silent rollback on Rails 7.0/7.1)#32
TalGruperFolloze wants to merge 1 commit into
rameerez:mainfrom
TalGruperFolloze:fix-transaction-exit-statements

Conversation

@TalGruperFolloze

Copy link
Copy Markdown

Fixes #31.

Rails' behavior for return out of a transaction/with_lock block changed across the versions this gem supports (rails >= 6.1): on 7.0, and on 7.1 without load_defaults 7.1, a non-local return silently rolls back the transaction while the method still returns normally.

Audited every transaction/with_lock block in lib/ for lexical return/break/throw and found three:

  • wallet.rb β€” Wallet#add_credits: return transaction β†’ transaction (the issue's report; every credit grant routes through this, so affected apps lose every grant with no error)
  • concerns/pay_subscription_extension.rb β€” plan-change handler: return after clear_pending_plan_change (which does an update!) β†’ next, so the metadata clear isn't rolled back
  • services/fulfillment_service.rb β€” FulfillmentService#process: early return unless due_for_fulfillment? β†’ next (nothing written before it, but same deprecated pattern)

The break in Wallet#deduct_credits is inside an inner each loop, not the transaction block, so it's fine. All other returns near transactions are in methods called from blocks, which are ordinary method returns.

Per the issue's definition of done, added a test that grants credits and asserts the transaction row and balance actually persist after the call (reloading the wallet), since the failure mode returns a truthy Transaction and only a persistence assertion catches it.

I skipped enabling Rails/TransactionExitStatement: the repo's RuboCop setup doesn't load rubocop-rails and RuboCop isn't wired into CI or the Rakefile, so the config would be inert β€” happy to add it if you'd like the dependency.

Tests: wallet_test.rb (63 runs), fulfillment_service_test.rb (32), pay_subscription_extension_test.rb (79) β€” all green on sqlite3.

πŸ€– Generated with Claude Code

…ails 7.0/7.1)

Fixes rameerez#31

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wallet#add_credits uses return inside a with_lock block β€” credit grants can silently roll back depending on Rails version

1 participant