From b11b1e868a89319b8523c5f7b0da4c130ee42992 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Mon, 18 Aug 2014 00:34:20 -0400 Subject: 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] --- .../connection_adapters/abstract/transaction.rb | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/abstract') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb index 8f06cf3a1f..90be835d8a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb @@ -22,6 +22,10 @@ module ActiveRecord @state == :rolledback end + def completed? + committed? || rolledback? + end + def set_state(state) if !VALID_STATES.include?(state) raise ArgumentError, "Invalid transaction state: #{state}" @@ -63,13 +67,19 @@ module ActiveRecord end def rollback_records - records.uniq.each do |record| + ite = records.uniq + while record = ite.shift begin record.rolledback! full_rollback? rescue => e + raise if ActiveRecord::Base.raise_in_transactional_callbacks record.logger.error(e) if record.respond_to?(:logger) && record.logger end end + ensure + ite.each do |i| + i.rolledback!(full_rollback?, false) + end end def commit @@ -77,13 +87,19 @@ module ActiveRecord end def commit_records - records.uniq.each do |record| + ite = records.uniq + while record = ite.shift begin record.committed! rescue => e + raise if ActiveRecord::Base.raise_in_transactional_callbacks record.logger.error(e) if record.respond_to?(:logger) && record.logger end end + ensure + ite.each do |i| + i.committed!(false) + end end def full_rollback?; true; end @@ -103,14 +119,14 @@ module ActiveRecord end def rollback - super connection.rollback_to_savepoint(savepoint_name) + super rollback_records end def commit - super connection.release_savepoint(savepoint_name) + super parent = connection.transaction_manager.current_transaction records.each { |r| parent.add_record(r) } end @@ -130,14 +146,14 @@ module ActiveRecord end def rollback - super connection.rollback_db_transaction + super rollback_records end def commit - super connection.commit_db_transaction + super commit_records end end @@ -177,7 +193,7 @@ module ActiveRecord begin commit_transaction unless error rescue Exception - transaction.rollback + transaction.rollback unless transaction.state.completed? raise end end -- cgit v1.2.3