Skip to content

Commit 07d3d40

Browse files
committed
Change transaction callbacks to not swallowing errors.
Before this change any error raised inside a transaction callback are rescued and printed in the logs. Now these errors are not rescue anymore and just bubble up, as the other callbacks.
1 parent 3a59dd2 commit 07d3d40

File tree

6 files changed

+25
-80
lines changed

6 files changed

+25
-80
lines changed

activerecord/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
* Deprecate `ActiveRecord::Base.errors_in_transactional_callbacks=`.
2+
3+
*Rafael Mendonça França*
4+
5+
* Change transaction callbacks to not swallowing errors.
6+
7+
Before this change any error raised inside a transaction callback are
8+
rescued and printed in the logs.
9+
10+
Now these errors are not rescue anymore and just bubble up, as the other callbacks.
11+
12+
*Rafael Mendonça França*
13+
114
* Remove deprecated `sanitize_sql_hash_for_conditions`.
215

316
*Rafael Mendonça França*

activerecord/lib/active_record/connection_adapters/abstract/transaction.rb

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,7 @@ def rollback
6969
def rollback_records
7070
ite = records.uniq
7171
while record = ite.shift
72-
begin
73-
record.rolledback! full_rollback?
74-
rescue => e
75-
raise if ActiveRecord::Base.raise_in_transactional_callbacks
76-
record.logger.error(e) if record.respond_to?(:logger) && record.logger
77-
end
72+
record.rolledback! full_rollback?
7873
end
7974
ensure
8075
ite.each do |i|
@@ -89,12 +84,7 @@ def commit
8984
def commit_records
9085
ite = records.uniq
9186
while record = ite.shift
92-
begin
93-
record.committed!
94-
rescue => e
95-
raise if ActiveRecord::Base.raise_in_transactional_callbacks
96-
record.logger.error(e) if record.respond_to?(:logger) && record.logger
97-
end
87+
record.committed!
9888
end
9989
ensure
10090
ite.each do |i|

activerecord/lib/active_record/transactions.rb

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,10 @@ module Transactions
44
extend ActiveSupport::Concern
55
#:nodoc:
66
ACTIONS = [:create, :destroy, :update]
7-
#:nodoc:
8-
CALLBACK_WARN_MESSAGE = "Currently, Active Record suppresses errors raised " \
9-
"within `after_rollback`/`after_commit` callbacks and only print them to " \
10-
"the logs. In the next version, these errors will no longer be suppressed. " \
11-
"Instead, the errors will propagate normally just like in other Active " \
12-
"Record callbacks.\n" \
13-
"\n" \
14-
"You can opt into the new behavior and remove this warning by setting:\n" \
15-
"\n" \
16-
" config.active_record.raise_in_transactional_callbacks = true\n\n"
177

188
included do
199
define_callbacks :commit, :rollback,
2010
scope: [:kind, :name]
21-
22-
mattr_accessor :raise_in_transactional_callbacks, instance_writer: false
23-
self.raise_in_transactional_callbacks = false
2411
end
2512

2613
# = Active Record Transactions
@@ -236,9 +223,6 @@ def transaction(options = {}, &block)
236223
def after_commit(*args, &block)
237224
set_options_for_callbacks!(args)
238225
set_callback(:commit, :after, *args, &block)
239-
unless ActiveRecord::Base.raise_in_transactional_callbacks
240-
ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
241-
end
242226
end
243227

244228
# This callback is called after a create, update, or destroy are rolled back.
@@ -247,9 +231,16 @@ def after_commit(*args, &block)
247231
def after_rollback(*args, &block)
248232
set_options_for_callbacks!(args)
249233
set_callback(:rollback, :after, *args, &block)
250-
unless ActiveRecord::Base.raise_in_transactional_callbacks
251-
ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
252-
end
234+
end
235+
236+
def raise_in_transactional_callbacks
237+
ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks is deprecated and will be removed without replacement.')
238+
true
239+
end
240+
241+
def raise_in_transactional_callbacks=(value)
242+
ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.')
243+
value
253244
end
254245

255246
private

activerecord/test/cases/helper.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
# Disable available locale checks to avoid warnings running the test suite.
2525
I18n.enforce_available_locales = false
2626

27-
# Enable raise errors in after_commit and after_rollback.
28-
ActiveRecord::Base.raise_in_transactional_callbacks = true
29-
3027
# Connect to the database
3128
ARTest.connect
3229

activerecord/test/cases/transaction_callbacks_test.rb

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -266,47 +266,6 @@ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
266266
assert_equal 2, @first.rollbacks
267267
end
268268

269-
def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
270-
old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
271-
ActiveRecord::Base.raise_in_transactional_callbacks = false
272-
273-
def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
274-
def @first.last_after_transaction_error; @last_transaction_error; end
275-
@first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
276-
@first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";}
277-
278-
second = TopicWithCallbacks.find(3)
279-
second.after_commit_block{|r| r.history << :after_commit}
280-
second.after_rollback_block{|r| r.history << :after_rollback}
281-
282-
Topic.transaction do
283-
@first.save!
284-
second.save!
285-
end
286-
assert_equal :commit, @first.last_after_transaction_error
287-
assert_equal [:after_commit], second.history
288-
289-
second.history.clear
290-
Topic.transaction do
291-
@first.save!
292-
second.save!
293-
raise ActiveRecord::Rollback
294-
end
295-
assert_equal :rollback, @first.last_after_transaction_error
296-
assert_equal [:after_rollback], second.history
297-
ensure
298-
ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
299-
end
300-
301-
def test_after_commit_should_not_raise_when_raise_in_transactional_callbacks_false
302-
old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
303-
ActiveRecord::Base.raise_in_transactional_callbacks = false
304-
@first.after_commit_block{ fail "boom" }
305-
Topic.transaction { @first.save! }
306-
ensure
307-
ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
308-
end
309-
310269
def test_after_commit_callback_should_not_swallow_errors
311270
@first.after_commit_block{ fail "boom" }
312271
assert_raises(RuntimeError) do

railties/lib/rails/generators/rails/app/templates/config/application.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,5 @@ class Application < Rails::Application
3131
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
3232
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
3333
# config.i18n.default_locale = :de
34-
<%- unless options.skip_active_record? -%>
35-
36-
# Do not swallow errors in after_commit/after_rollback callbacks.
37-
config.active_record.raise_in_transactional_callbacks = true
38-
<%- end -%>
3934
end
4035
end

0 commit comments

Comments
 (0)