Skip to content

Commit

Permalink
Logs an error in the Rails logs when installment processing fails
Browse files Browse the repository at this point in the history
At the moment, by default, all installment prceissing errors are
swallowed and there's no way for a developer to understand what's
happening. Of course they can create a custom handler with the
processing_error_handler configuration provided but usually, when
the first errors happen, it's too late and those errors are lost.

We are not raising errors of this job because if there's a retry
mechanism in place for Active Job, the installment will be
reprocessed twice. Once by Active Job and once by the installment
retry mechanism already provided by the extension.

Logging to Rails.error is a middle-ground that allows to intercept
the message of the exception. Still, creating a custom handler
based on the bug tracker/exception handler used is the suggested
option here.
  • Loading branch information
kennyadsl committed Jul 13, 2021
1 parent 6627196 commit c9e2619
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
# 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.processing_error_handler = nil
#
# By default, it only logs the error message using Rails.logger.error.
# config.processing_error_handler = SolidusSubscriptions::ProcessingErrorHandlers::RailsLogger

# ========================================= Dispatchers ==========================================
#
Expand Down
9 changes: 7 additions & 2 deletions lib/solidus_subscriptions/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ module SolidusSubscriptions
class Configuration
attr_accessor(
:maximum_total_skips, :maximum_reprocessing_time, :churn_buster_account_id,
:churn_buster_api_key, :clear_past_installments, :processing_error_handler
:churn_buster_api_key, :clear_past_installments
)

attr_writer(
: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, :order_creator_class
:subscription_attributes, :subscribable_class, :order_creator_class, :processing_error_handler
)

def success_dispatcher_class
Expand All @@ -34,6 +34,11 @@ def out_of_stock_dispatcher_class
@out_of_stock_dispatcher_class.constantize
end

def processing_error_handler
@processing_error_handler ||= 'SolidusSubscriptions::ProcessingErrorHandlers::RailsLogger'
@processing_error_handler.constantize
end

def maximum_successive_skips
@maximum_successive_skips ||= 1
end
Expand Down
1 change: 1 addition & 0 deletions lib/solidus_subscriptions/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'solidus_subscriptions/permitted_attributes'
require 'solidus_subscriptions/configuration'
require 'solidus_subscriptions/processor'
require 'solidus_subscriptions/processing_error_handlers/rails_logger'

module SolidusSubscriptions
class Engine < Rails::Engine
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module SolidusSubscriptions
module ProcessingErrorHandlers
class RailsLogger
def self.call(exception)
new(exception).call
end

def initialize(exception)
@exception = exception
end

def call
Rails.logger.error exception.message
end

private

attr_reader :exception
end
end
end
15 changes: 15 additions & 0 deletions spec/jobs/solidus_subscriptions/process_installment_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@
end

context 'when handling #perform errors' do
it 'by default logs exception data without raising exceptions' do
checkout = instance_double(SolidusSubscriptions::Checkout).tap do |c|
allow(c).to receive(:process).and_raise('test error')
end
allow(SolidusSubscriptions::Checkout).to receive(:new).and_return(checkout)
allow(Rails.logger).to receive(:error)

expect {
described_class.perform_now(build_stubbed(:installment))
}.not_to raise_error

expect(Rails.logger).to have_received(:error).with("test error").ordered
end

it 'swallows error when a proc is not configured' do
stub_config(processing_error_handler: nil )
checkout = instance_double(SolidusSubscriptions::Checkout).tap do |c|
allow(c).to receive(:process).and_raise('test error')
end
Expand Down

0 comments on commit c9e2619

Please sign in to comment.