Class: StripeModelCallbacks::BaseService

Inherits:
ServicePattern::Service
  • Object
show all
Defined in:
app/services/stripe_model_callbacks/base_service.rb

Class Method Summary collapse

Class Method Details

.advisory_lock_id(stripe_event_data) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'app/services/stripe_model_callbacks/base_service.rb', line 48

def self.advisory_lock_id(stripe_event_data)
  return stripe_event_data.id if stripe_event_data.respond_to?(:id)
  return stripe_event_data.coupon.id if stripe_event_data.object == "discount"
  return unless stripe_event_data.respond_to?(:customer)

  if stripe_event_data.customer.is_a?(String)
    stripe_event_data.customer
  else
    stripe_event_data.customer.id
  end
end

.advisory_lock_name(event:) ⇒ Object



42
43
44
45
46
# File 'app/services/stripe_model_callbacks/base_service.rb', line 42

def self.advisory_lock_name(event:)
  stripe_event_data = event.data.object

  ["stripe", stripe_event_data.object, "id", advisory_lock_id(stripe_event_data)].join("-")
end

.execute_with_advisory_lock!(*args, **opts, &blk) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/services/stripe_model_callbacks/base_service.rb', line 28

def self.execute_with_advisory_lock!(*args, **opts, &blk)
  # The difference between the stripe events is about a few milliseconds - with advisory_lock
  # we will prevent from creating duplicated objects due to race condition.
  # https://stripe.com/docs/webhooks/best-practices#event-ordering
  with_exception_notifications do
    StripeModelCallbacks::ApplicationRecord.with_advisory_lock(advisory_lock_name(*args, **opts)) do
      response = execute(*args, **opts, &blk)
      raise response.errors.join(". ") unless response.success?

      response
    end
  end
end

.reported_execute!(*args, **opts, &blk) ⇒ Object



2
3
4
5
6
7
8
9
# File 'app/services/stripe_model_callbacks/base_service.rb', line 2

def self.reported_execute!(*args, **opts, &blk)
  with_exception_notifications do
    response = execute(*args, **opts, &blk)
    raise response.errors.join(". ") unless response.success?

    response
  end
end

.with_exception_notificationsObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/services/stripe_model_callbacks/base_service.rb', line 11

def self.with_exception_notifications
  yield
rescue => e # rubocop:disable Style/RescueStandardError
  Rails.logger.error "ERROR: #{e.message}"

  cleaned = Rails.backtrace_cleaner.clean(e.backtrace)
  if cleaned.any?
    Rails.logger.error cleaned
  else
    Rails.logger.error e.backtrace.join("\n")
  end

  ExceptionNotifier.notify_exception(e) if Object.const_defined?(:ExceptionNotifier)
  PeakFlowUtils::Notifier.notify(error: e) if Object.const_defined?(:PeakFlowUtils)
  raise e
end