Reputation: 16491
I'm trying to reduce the duplicate code I'm using to create
and capture
payments using the Stripe::PaymentIntents
class. Both methods have the same error handling that I'd like to reduce down to one block, but unsure how to achieve this? I'm thinking I need to use the public send method with arguments to cover the calls, but I'm not sure how to return the errors if they would occur or the correct response on success?
Code:
STRIPE_ERRORS = [
Stripe::CardError,
Stripe::RateLimitError,
Stripe::InvalidRequestError,
Stripe::AuthenticationError,
Stripe::APIConnectionError,
Stripe::StripeError
].freeze
def capture
payment_intent_id = params[:payment_intent_id]
return render_unprocessable_entity('payment_intent_id is required') unless payment_intent_id.present?
payment_capture = handle_request('capture', payment_intent_id)
render json: {info: payment_capture.info}, status: :ok
end
def handle_request(method, params)
begin
req = Stripe::PaymentIntent.send(method, params)
rescue *STRIPE_ERRORS => e
Rails.logger.warn(e)
return render json: { error: e }, status: e.http_status
rescue StandardError => e
Rails.logger.error(e)
return render json: { error: 'Internal server error' }, status: :internal_server_error
end
puts "req:: #{req}"
req
end
Upvotes: 2
Views: 364
Reputation: 26768
There are multiple ways to do this. But just to show that you don't need any magic method for it, here's a simple way using a block (anonymous function):
# returns [request, error] array
def rescue_stripe_errors(&block)
begin
req = block.call
[req, nil]
rescue *STRIPE_ERRORS => e
[nil, e]
end
end
Now if you call this you will get a hash with req
and error
keys. One of them will have a value and the other one will be nil. After calling the function, you can check if the error is nil and proceed accordingly.
def handle_request(method, params)
req, e = rescue_stripe_errors do
Stripe::PaymentIntent.send(method, params)
end
if e
Rails.logger.warn(e)
return render json: { error: e }, status: e.http_status
end
puts "req:: #{req}"
req
end
Upvotes: 4