From ba62ffe9bd7425dec2c786a3713b2c6d73dfabfb Mon Sep 17 00:00:00 2001 From: lalopsb Date: Wed, 10 Mar 2021 15:26:05 -0300 Subject: [PATCH 1/3] Add support for manual errors within transactions --- lib/exception_hunter/tracking.rb | 20 +++++++++++++++++++- spec/exception_hunter_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/exception_hunter/tracking.rb b/lib/exception_hunter/tracking.rb index 0eb4e4b..fdde75a 100644 --- a/lib/exception_hunter/tracking.rb +++ b/lib/exception_hunter/tracking.rb @@ -19,6 +19,22 @@ module Tracking # @param [User] user in the current session. (optional) # @return [void] def track(exception, custom_data: {}, user: nil) + open_transactions? ? create_error_within_new_thread(exception, custom_data, user) : create_error(exception, custom_data, user) + + nil + end + + private + + def create_error_within_new_thread(exception, custom_data, user) + Thread.new do + ActiveRecord::Base.connection_pool.with_connection do + create_error(exception, custom_data, user) + end + end + end + + def create_error(exception, custom_data, user) ErrorCreator.call( tag: ErrorCreator::MANUAL_TAG, class_name: exception.class.to_s, @@ -28,8 +44,10 @@ def track(exception, custom_data: {}, user: nil) user: user, environment_data: {} ) + end - nil + def open_transactions? + ActiveRecord::Base.connection.open_transactions.positive? end end end diff --git a/spec/exception_hunter_spec.rb b/spec/exception_hunter_spec.rb index e6fb09b..26da776 100644 --- a/spec/exception_hunter_spec.rb +++ b/spec/exception_hunter_spec.rb @@ -17,6 +17,8 @@ module ExceptionHunter let(:user) { OpenStruct.new(id: 3, email: 'example@example.com', name: 'John') } context 'when tracking is enabled' do + before { allow(ActiveRecord::Base.connection).to receive(:open_transactions).and_return(0) } + let(:error) { Error.last } it 'creates a new error' do @@ -55,6 +57,24 @@ module ExceptionHunter expect(error.error_group.tags).to eq(['Manual']) end + + it ' does not create a new thread' do + expect(Thread).to_not receive(:new) + + subject + end + + context 'when the error is tracked within a transaction' do + before do + allow(ActiveRecord::Base.connection).to receive(:open_transactions).and_return(1) + allow(Thread).to receive(:new).and_yield + end + + it 'creates a new error within a new thread' do + expect { subject }.to change(Error, :count).by(1) + expect(Thread).to have_received(:new) + end + end end context 'when tracking is disabled' do From ccb0dee666670eaa129e9731bdae2237c8b3e39d Mon Sep 17 00:00:00 2001 From: lalopsb Date: Wed, 10 Mar 2021 15:45:07 -0300 Subject: [PATCH 2/3] Add to CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb8b68a..c88d8dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ### New features - [#113](https://github.com/rootstrap/exception_hunter/pull/113) Add configuration to turn on/off async logging using ActionJob. ( - [@matteo95g][]) + [@matteo95g][]) +- [#119](https://github.com/rootstrap/exception_hunter/pull/119) Add support for tracking manual exceptions within transactions. ([@lalopsb][]) ### Bug fixes From c62647681e1fd03c1f345217dcdfe4ed366de765 Mon Sep 17 00:00:00 2001 From: lalopsb Date: Wed, 10 Mar 2021 16:28:39 -0300 Subject: [PATCH 3/3] Enforce immediate join of thread and fix linting errors --- .reek.yml | 1 + lib/exception_hunter/tracking.rb | 10 +++++++--- spec/exception_hunter_spec.rb | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.reek.yml b/.reek.yml index 279e5dc..d6c82d7 100644 --- a/.reek.yml +++ b/.reek.yml @@ -20,6 +20,7 @@ detectors: enabled: true exclude: - ExceptionHunter::ErrorCreator + - ExceptionHunter::Tracking max_copies: 2 min_clump_size: 2 diff --git a/lib/exception_hunter/tracking.rb b/lib/exception_hunter/tracking.rb index fdde75a..c34a04f 100644 --- a/lib/exception_hunter/tracking.rb +++ b/lib/exception_hunter/tracking.rb @@ -19,7 +19,11 @@ module Tracking # @param [User] user in the current session. (optional) # @return [void] def track(exception, custom_data: {}, user: nil) - open_transactions? ? create_error_within_new_thread(exception, custom_data, user) : create_error(exception, custom_data, user) + if open_transactions? + create_error_within_new_thread(exception, custom_data, user) + else + create_error(exception, custom_data, user) + end nil end @@ -27,11 +31,11 @@ def track(exception, custom_data: {}, user: nil) private def create_error_within_new_thread(exception, custom_data, user) - Thread.new do + Thread.new { ActiveRecord::Base.connection_pool.with_connection do create_error(exception, custom_data, user) end - end + }.join end def create_error(exception, custom_data, user) diff --git a/spec/exception_hunter_spec.rb b/spec/exception_hunter_spec.rb index 26da776..692387d 100644 --- a/spec/exception_hunter_spec.rb +++ b/spec/exception_hunter_spec.rb @@ -67,7 +67,7 @@ module ExceptionHunter context 'when the error is tracked within a transaction' do before do allow(ActiveRecord::Base.connection).to receive(:open_transactions).and_return(1) - allow(Thread).to receive(:new).and_yield + allow(Thread).to receive(:new).and_call_original end it 'creates a new error within a new thread' do