aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
authorArthur Neves <arthurnn@gmail.com>2014-08-18 00:34:20 -0400
committerArthur Neves <arthurnn@gmail.com>2014-08-18 14:47:48 -0400
commitb11b1e868a89319b8523c5f7b0da4c130ee42992 (patch)
treea93feaa55fba0e6d716362c5d6ee07edac2ea1cb /activerecord/test
parente759b5277e404cb0ca8353d0c6eba8a5c471af41 (diff)
downloadrails-b11b1e868a89319b8523c5f7b0da4c130ee42992.tar.gz
rails-b11b1e868a89319b8523c5f7b0da4c130ee42992.tar.bz2
rails-b11b1e868a89319b8523c5f7b0da4c130ee42992.zip
Add option to stop swallowing errors on callbacks.
Currently, Active Record will rescue any errors raised within after_rollback/after_create callbacks and print them to the logs. Next versions of rails will not rescue those errors anymore, and just bubble them up, as the other callbacks. This adds a opt-in flag to enable that behaviour, of not rescuing the errors. Example: # For not swallow errors in after_commit/after_rollback config.active_record.errors_in_transactional_callbacks = true [fixes #13460]
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/helper.rb3
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb76
2 files changed, 79 insertions, 0 deletions
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 6a8aff4b69..e43b796237 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -24,6 +24,9 @@ ActiveSupport::Deprecation.debug = true
# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false
+# Enable raise errors in after_commit and after_rollback.
+ActiveRecord::Base.raise_in_transactional_callbacks = true
+
# Connect to the database
ARTest.connect
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index a3f39804b7..b5ac1bdaf9 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -267,6 +267,9 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
end
def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
+ old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
+ ActiveRecord::Base.raise_in_transactional_callbacks = false
+
def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
def @first.last_after_transaction_error; @last_transaction_error; end
@first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
@@ -291,6 +294,79 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
end
assert_equal :rollback, @first.last_after_transaction_error
assert_equal [:after_rollback], second.history
+ ensure
+ ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
+ end
+
+ def test_after_commit_should_not_raise_when_raise_in_transactional_callbacks_false
+ old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
+ ActiveRecord::Base.raise_in_transactional_callbacks = false
+ @first.after_commit_block{ fail "boom" }
+ Topic.transaction { @first.save! }
+ ensure
+ ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
+ end
+
+ def test_after_commit_callback_should_not_swallow_errors
+ @first.after_commit_block{ fail "boom" }
+ assert_raises(RuntimeError) do
+ Topic.transaction do
+ @first.save!
+ end
+ end
+ end
+
+ def test_after_commit_callback_when_raise_should_not_restore_state
+ first = TopicWithCallbacks.new
+ second = TopicWithCallbacks.new
+ first.after_commit_block{ fail "boom" }
+ second.after_commit_block{ fail "boom" }
+
+ begin
+ Topic.transaction do
+ first.save!
+ assert_not_nil first.id
+ second.save!
+ assert_not_nil second.id
+ end
+ rescue
+ end
+ assert_not_nil first.id
+ assert_not_nil second.id
+ assert first.reload
+ end
+
+ def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
+ error_class = Class.new(StandardError)
+ @first.after_rollback_block{ raise error_class }
+ assert_raises(error_class) do
+ Topic.transaction do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+ end
+ end
+
+ def test_after_rollback_callback_when_raise_should_restore_state
+ error_class = Class.new(StandardError)
+
+ first = TopicWithCallbacks.new
+ second = TopicWithCallbacks.new
+ first.after_rollback_block{ raise error_class }
+ second.after_rollback_block{ raise error_class }
+
+ begin
+ Topic.transaction do
+ first.save!
+ assert_not_nil first.id
+ second.save!
+ assert_not_nil second.id
+ raise ActiveRecord::Rollback
+ end
+ rescue error_class
+ end
+ assert_nil first.id
+ assert_nil second.id
end
def test_after_rollback_callbacks_should_validate_on_condition