From 28e9291ecdf010a4f87ee1cb8d2856d766ad0f75 Mon Sep 17 00:00:00 2001 From: Ikraam Ghoor Date: Sat, 27 Feb 2021 08:43:45 +0200 Subject: Skip ActiveJob retrying for ProcessInstallmentJob This disables the ActiveJob default retry mechanism because installment processing failures are already taken care of by solidus_subscriptions. Before this, there was a potentional for double retrying, which could causes background jobs and cancelled orders to accumulate leading to side effects such as a bad customer experience. Now, a `process_job_error_handler` configuration Proc is called when a ProcessInstallmentJob `#perfom` method fails. The rescued error can be managed/logged as preffered, or re-raised if the default retry behaviour is required in the job. --- app/jobs/solidus_subscriptions/process_installment_job.rb | 2 ++ .../solidus_subscriptions/install/templates/initializer.rb | 7 +++++++ lib/solidus_subscriptions/configuration.rb | 6 +++++- .../solidus_subscriptions/process_installment_job_spec.rb | 12 ++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/jobs/solidus_subscriptions/process_installment_job.rb b/app/jobs/solidus_subscriptions/process_installment_job.rb index 127c787..8add4f2 100644 --- a/app/jobs/solidus_subscriptions/process_installment_job.rb +++ b/app/jobs/solidus_subscriptions/process_installment_job.rb @@ -6,6 +6,8 @@ module SolidusSubscriptions def perform(installment) Checkout.new(installment).process + rescue StandardError => e + SolidusSubscriptions.configuration.process_job_error_handler&.call(e) end end end diff --git a/lib/generators/solidus_subscriptions/install/templates/initializer.rb b/lib/generators/solidus_subscriptions/install/templates/initializer.rb index 31e44b5..e0a0af7 100644 --- a/lib/generators/solidus_subscriptions/install/templates/initializer.rb +++ b/lib/generators/solidus_subscriptions/install/templates/initializer.rb @@ -26,6 +26,13 @@ SolidusSubscriptions.configure do |config| # failure cancel the subscription. # config.maximum_reprocessing_time = nil + # This custom error handler is called when a ProcessInstallmentJob `#perform` method fails. + # The rescued error can be managed as requried via a Proc, such as one which logs the error + # on an error tracking system. + # Though not recommended due to the retry mechanisms built into this gem, the error can be + # re-raised if the default retry behaviour is required in ActiveJob. + # config.process_job_error_handler = nil + # ========================================= Dispatchers ========================================== # # These dispatchers are pluggable. If you override any handlers, it is highly encouraged that you diff --git a/lib/solidus_subscriptions/configuration.rb b/lib/solidus_subscriptions/configuration.rb index 536aad3..6e4479d 100644 --- a/lib/solidus_subscriptions/configuration.rb +++ b/lib/solidus_subscriptions/configuration.rb @@ -11,7 +11,7 @@ module SolidusSubscriptions :success_dispatcher_class, :failure_dispatcher_class, :payment_failed_dispatcher_class, :out_of_stock_dispatcher, :maximum_successive_skips, :reprocessing_interval, :minimum_cancellation_notice, :processing_queue, :subscription_line_item_attributes, - :subscription_attributes, :subscribable_class, + :subscription_attributes, :subscribable_class, :process_job_error_handler, ) def success_dispatcher_class @@ -80,5 +80,9 @@ module SolidusSubscriptions def churn_buster? churn_buster_account_id.present? && churn_buster_api_key.present? end + + def process_job_error_handler + @process_job_error_handler ||= nil + end end end diff --git a/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb b/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb index 4a33819..6fe8ed2 100644 --- a/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb +++ b/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb @@ -8,4 +8,16 @@ RSpec.describe SolidusSubscriptions::ProcessInstallmentJob do expect(checkout).to have_received(:process) end + + context 'when handling #perform errors' do + it 'swallows error on #perfom error' do + expect { described_class.perform_now(nil) }.not_to raise_error(StandardError) + end + + it 'runs proc on #perform error' do + stub_config(process_job_error_handler: proc { |e| raise e } ) + + expect { described_class.perform_now(nil) }.to raise_error(StandardError) + end + end end -- cgit v1.2.3