Skip to content

Commit 38b1b99

Browse files
committed
Exception in a callback tx should stop other callbacks within same tx
1 parent 1f45a92 commit 38b1b99

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

lib/after_commit_everywhere/wrap.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ def trigger_transactional_callbacks?
2323
true
2424
end
2525

26-
def committed!(*)
27-
@handlers[:after_commit]&.call
26+
def committed!(should_run_callbacks: true)
27+
if should_run_callbacks
28+
@handlers[:after_commit]&.call
29+
end
2830
end
2931

3032
def rolledback!(*)

spec/after_commit_everywhere_spec.rb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
end
2929

3030
context "within transaction" do
31-
context 'when prepend is true' do
32-
let(:handler_1) { spy("handler_1") }
33-
let(:handler_2) { spy("handler_2") }
31+
let(:handler_1) { spy("handler_1") }
32+
let(:handler_2) { spy("handler_2") }
3433

34+
context 'when prepend is true' do
3535
it 'executes prepended callback first' do
3636
ActiveRecord::Base.transaction do
3737
example_class.new.after_commit { handler_1.call }
@@ -54,9 +54,6 @@
5454
end
5555

5656
context 'when prepend is not specified' do
57-
let(:handler_1) { spy("handler_1") }
58-
let(:handler_2) { spy("handler_2") }
59-
6057
it 'executes callbacks in the order they were defined' do
6158
ActiveRecord::Base.transaction do
6259
example_class.new.after_commit { handler_1.call }
@@ -99,6 +96,18 @@
9996
expect(handler).to have_received(:call)
10097
end
10198
end
99+
100+
it 'propagates an error raised in one of multiple callbacks' do
101+
expect do
102+
ActiveRecord::Base.transaction do
103+
example_class.new.after_commit { raise 'this should prevent other callbacks being executed' }
104+
example_class.new.after_commit { handler_1.call }
105+
example_class.new.after_commit { handler_2.call }
106+
end
107+
end.to raise_error('this should prevent other callbacks being executed')
108+
expect(handler_1).not_to have_received(:call)
109+
expect(handler_2).not_to have_received(:call)
110+
end
102111
end
103112

104113
context "without transaction" do

0 commit comments

Comments
 (0)