捕获错误并暂停程序的正确方法是什么?

时间:2018-08-13 15:31:55

标签: ruby-on-rails

我的目的是在验证失败(使用干燥验证)后中断并向用户返回错误。

在服务对象中,我有:

def perform
  validate_coupon
  create_stripe_coupon
rescue ActiveRecord::RecordInvalid, ::Stripe::StripeError => exception
  puts "[STRIPE] Problem: #{exception.message}"
  OpenStruct.new(success?: false, coupon: coupon, error: exception.message)
else
  OpenStruct.new(success?: true, coupon: coupon)
end

def validate_coupon
  validate_coupon_object
rescue CouponError => exception
  puts "[CouponError] #{exception.message}"
  OpenStruct.new(success?: false, coupon: coupon, error: exception.message)
else
  OpenStruct.new(success?: true, coupon: coupon)
end

def create_stripe_coupon
  @coupon = ::Stripe::Coupon.create(
    :name => @coupon.name,
    :duration => @coupon.duration,
    :percent_off => @coupon.percent_off,
    :max_redemptions => @coupon.max_redemptions
    )
  save_coupon_object
end

我在validate_coupon.rb中提出了一个自定义错误:

module PaymentServices
  module Stripe
    module Coupon
      module ValidateCoupon

        def schema
          Dry::Validation.Schema do
            required(:name) { str? }
            required(:duration) { str? }
            required(:percent_off) { gt?(0) & lt?(101) }
            required(:max_redemptions) { int? & gt?(0) }
          end
        end

        def validate_coupon_object
          result = schema.call(
            name: @coupon.name,
            duration: @coupon.duration,
            percent_off: @coupon.percent_off,
            max_redemptions: @coupon.max_redemptions
            )
          raise CouponError.new(result) if result.failure?
        end

      end
    end
  end
end

验证失败时,程序将引发错误,但会继续执行create_stripe_coupon

我的愿望是在validate_coupon内引发错误时中断,从而停止运行create_stripe_coupon

什么是最好的方法?

1 个答案:

答案 0 :(得分:0)

问题在于,该异常是通过validate_coupon方法抢救的:

def validate_coupon
  validate_coupon_object
rescue CouponError => exception
  puts "[CouponError] #{exception.message}"
  OpenStruct.new(success?: false, coupon: coupon, error: exception.message)
else
  OpenStruct.new(success?: true, coupon: coupon)
end

perform方法对validate_coupon方法中发生的故障一无所知:

def perform
  validate_coupon
  create_stripe_coupon
rescue ActiveRecord::RecordInvalid, ::Stripe::StripeError => exception
  puts "[STRIPE] Problem: #{exception.message}"
  OpenStruct.new(success?: false, coupon: coupon, error: exception.message)
else
  OpenStruct.new(success?: true, coupon: coupon)
end

要修复它,您需要类似以下内容的

def perform
  result = validate_coupon
  create_stripe_coupon if result.success?
rescue ActiveRecord::RecordInvalid, ::Stripe::StripeError => exception
  puts "[STRIPE] Problem: #{exception.message}"
  OpenStruct.new(success?: false, coupon: coupon, error: exception.message)
else
  OpenStruct.new(success?: true, coupon: coupon)
end

def validate_coupon
  validate_coupon_object
rescue CouponError => exception
  puts "[CouponError] #{exception.message}"
  raise ActiveRecord::RecordInvalid
end