From 81d99221b9f9a9df9306bf3ec1d1903992ef6cd1 Mon Sep 17 00:00:00 2001 From: "Kevin (bum)" Date: Mon, 9 Dec 2024 23:22:44 +0900 Subject: [PATCH] Propagatable exception after committed DB transaction (#35) See discussion at https://github.com/Envek/after_commit_everywhere/issues/34 for details --- CHANGELOG.md | 21 +++++++++++++++------ Gemfile.lock | 2 +- lib/after_commit_everywhere/version.rb | 2 +- lib/after_commit_everywhere/wrap.rb | 6 ++++-- spec/after_commit_everywhere_spec.rb | 21 +++++++++++++++------ 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d7e1fc..cfa1478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,18 +4,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 1.5.0 (2024-12-09) + +### Added + +- Ability to propagate exception for multiple `after_commit` callbacks within transaction. Should handle exception inside callback to avoid stopping other callbacks. + + [Pull request #35](https://github.com/Envek/after_commit_everywhere/pull/35) by [@kevink1103](). Also see discussion at [#34](https://github.com/Envek/after_commit_everywhere/issues/34). + ## 1.4.0 (2024-02-07) ### Added - - Ability to prepend callbacks to the head of callback queue using `prepend: true` option. +- Ability to prepend callbacks to the head of callback queue using `prepend: true` option. - ```ruby - AfterCommitEverywhere.after_commit { puts "I'm second!" } - AfterCommitEverywhere.after_commit(prepend: true) { puts "I'm first!" } - ``` + ```ruby + AfterCommitEverywhere.after_commit { puts "I'm second!" } + AfterCommitEverywhere.after_commit(prepend: true) { puts "I'm first!" } + ``` - See [Pull request #30](https://github.com/Envek/after_commit_everywhere/pull/30) by [@quentindemetz][] and [@A1090][]. + See [Pull request #30](https://github.com/Envek/after_commit_everywhere/pull/30) by [@quentindemetz][] and [@A1090][]. ## 1.3.1 (2023-06-21) @@ -147,3 +155,4 @@ See [#11](https://github.com/Envek/after_commit_everywhere/issues/11) for discus [@jpcamara]: https://github.com/jpcamara "JP Camara" [@quentindemetz]: https://github.com/quentindemetz "Quentin de Metz" [@A1090]: https://github.com/A1090 "Tabac Andreina" +[@kevink1103]: https://github.com/kevink1103 "Kevin (bum)" diff --git a/Gemfile.lock b/Gemfile.lock index 1066372..d1f3574 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - after_commit_everywhere (1.4.0) + after_commit_everywhere (1.5.0) activerecord (>= 4.2) activesupport diff --git a/lib/after_commit_everywhere/version.rb b/lib/after_commit_everywhere/version.rb index 609ff56..fc3ce08 100644 --- a/lib/after_commit_everywhere/version.rb +++ b/lib/after_commit_everywhere/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module AfterCommitEverywhere - VERSION = "1.4.0" + VERSION = "1.5.0" end diff --git a/lib/after_commit_everywhere/wrap.rb b/lib/after_commit_everywhere/wrap.rb index 0f44ae9..66f19af 100644 --- a/lib/after_commit_everywhere/wrap.rb +++ b/lib/after_commit_everywhere/wrap.rb @@ -23,8 +23,10 @@ def trigger_transactional_callbacks? true end - def committed!(*) - @handlers[:after_commit]&.call + def committed!(should_run_callbacks: true) + if should_run_callbacks + @handlers[:after_commit]&.call + end end def rolledback!(*) diff --git a/spec/after_commit_everywhere_spec.rb b/spec/after_commit_everywhere_spec.rb index de1d6c2..18f6088 100644 --- a/spec/after_commit_everywhere_spec.rb +++ b/spec/after_commit_everywhere_spec.rb @@ -28,10 +28,10 @@ end context "within transaction" do - context 'when prepend is true' do - let(:handler_1) { spy("handler_1") } - let(:handler_2) { spy("handler_2") } + let(:handler_1) { spy("handler_1") } + let(:handler_2) { spy("handler_2") } + context 'when prepend is true' do it 'executes prepended callback first' do ActiveRecord::Base.transaction do example_class.new.after_commit { handler_1.call } @@ -54,9 +54,6 @@ end context 'when prepend is not specified' do - let(:handler_1) { spy("handler_1") } - let(:handler_2) { spy("handler_2") } - it 'executes callbacks in the order they were defined' do ActiveRecord::Base.transaction do example_class.new.after_commit { handler_1.call } @@ -99,6 +96,18 @@ expect(handler).to have_received(:call) end end + + it 'propagates an error raised in one of multiple callbacks' do + expect do + ActiveRecord::Base.transaction do + example_class.new.after_commit { raise 'this should prevent other callbacks being executed' } + example_class.new.after_commit { handler_1.call } + example_class.new.after_commit { handler_2.call } + end + end.to raise_error('this should prevent other callbacks being executed') + expect(handler_1).not_to have_received(:call) + expect(handler_2).not_to have_received(:call) + end end context "without transaction" do