I have a rails application that uses Stripe for credit card processing. Currently several exceptions are being handled anywhere a transaction takes place. The code below is being used currently in 11 places. In all places it is essentially the same with the exception of the message being passed to stripe_error
. Is it possible to create a reusable piece of code that can be used in all these places?
begin
charge = Stripe::Charge.retrieve(@purchase.stripe_charge_id)
resp = charge.capture(amount: fee.cancellation_fee,
receipt_email: @customer.email)
@purchase.update_attributes(
accepted_charge: true,
stripe_transaction_id: resp['balance_transaction']
)
logger.info("Charged customer for cancellation #{@customer.id} #{@purchase.total_fee}")
event('cancellation_charge', 'purchase_id', @purchase.id,
fee: @purchase.total_fee, customer_id: @purchase.customer_id,
provider_id: @purchase.provider_id)
purchase_set_md5(@purchase.id)
rescue Stripe::CardError => e
@err = stripe_error(e, 'cancellation', fee.cancellation_fee)
@purchase.update_attributes(
accepted_charge: false,
charge_errors: message,
stripe_transaction_id: '',
status: "Cancellation fee charge did not go through #{@err['message']}"
)
purchase_set_md5(@purchase.id)
render :err_show, status: :payment_required, json: @err
return
rescue Stripe::InvalidRequestError => e
@err = stripe_error(e, 'cancellation_invalid_request', fee.cancellation_fee)
render :err_show, status: :payment_required, json: @err
return
rescue Stripe::AuthenticationError => e
@err = stripe_error(e, 'cancellation_authentication', fee.cancellation_fee)
render :err_show, status: :payment_required, json: @err
return
rescue Stripe::APIConnectionError => e
@err = stripe_error(e, 'cancellation_api_connect', fee.cancellation_fee)
render :err_show, status: :payment_required, json: @err
return
rescue Stripe::StripeError => e
@err = stripe_error(e, 'cancellation_generic error', fee.cancellation_fee)
render :err_show, status: :payment_required, json: @err
return
rescue => e
@err = stripe_error(e, 'cancellation_something_else', fee.cancellation_fee)
render :err_show, status: :payment_required, json: @err
return
end
stripe_error
def stripe_error(e, charge_type, fee = 0)
logger.error("e #{e}")
err = {
charge_type: charge_type,
errcode: ERR_STRIPE_ERR,
message: "#{e}"
}
event(charge_type, 'error', "#{e}")
logger.error("Charging error on #{charge_type} purchase for #{fee} ")
logger.error("type #{e} ")
err
end
1 Answer 1
Your first step would be to separate out actually rendering the error message from rescueing the exceptions:
def render_errors(errors, template: :err_show, status: :payment_required)
render template, status: status, json: errors
end
Then can you group the majority of the exceptions:
rescue Stripe::InvalidRequestError,
Stripe::AuthenticationError
Stripe::APIConnectionError,
Stripe::StripeError => e
render_errors( stripe_error(e) )
A good idea would be then to separate generating the errors and logging them.
Explore related questions
See similar questions with these tags.
is_a?
of the exception later to change the string you use when you forward it \$\endgroup\$stripe_error
method does, which isn't included in the code posted. \$\endgroup\$stripe_error
code . Thanks \$\endgroup\$