cloud_payments
cloud_payments copied to clipboard
Неизвестная ошибка
Недавно в этом месте:
https://github.com/undr/cloud_payments/blob/c6f5ed680b2d9c8808bd932faca870937bc00590/lib/cloud_payments/namespaces/base.rb#L38-L40
Несколько раз выскочило NoMethodError · undefined method
new' for nil:NilClass`
Предлагаю такое решение:
def raise_reasoned_gateway_error(body)
return unless reason_present?(body)
error_class = Client::GATEWAY_ERRORS[body[:model][:reason_code]]
fail error_class.new(body) if error_class
end
Выглядит неплохо. Но может быть проблема в том что в API добавили новый тип ошибки. Не лучше ли добавить этот тип в список? Просто не понятно каким образом там появился nil
Может и добавили, то мы то откуда знаем? :) мы же обслуживаем софт, нам нужно в error.log видеть конкретно ошибку в момент ее появления, а не через месяц когда ее добавят в API.
Конкретно вот я вижу - NoMethodError · undefined methodnew' for nil:NilClass и не знаю толи это у клиента карточка просроченная, толи что вообще.
@undr самое интересное что когда мы только подключали CloudPayments я был точно такого-же мнения как ты написал выше, а теперь, когда только поддерживаем уже рабочий проект понимаю что мне нужно знать что с ним происходит в настоящее время, и чем меньше неизвестностей, тем лучше.
С именованием классов ошибок вообще еще сложнее чем с именованием классов. В данном случае, думаю, было бы уместнее иметь всего ТРИ класса ошибок (фатальные, с сетью и такие которые можно повторить). потому что сейчас обработка запроса выглядит так:
def call
logger.info 'Старт'
# Устанавливаем переменную объекта чтобы ею можно было воспользоваться из bugsnag
@cloud_payments_transaction = charge!
logger.info "Включаю услугу"
Billing::IncomeFromCloudPayments.perform @cloud_payments_transaction
log_charge 'finish'
rescue CloudPayments::Client::GatewayErrors::InsufficientFunds => err
error! err, err.message, :retry
logger.warn "На карте не хватает средств для оплаты услуг #{payment_account} #{err.message}"
false
rescue CloudPayments::Client::GatewayErrors::AntiFraud,
CloudPayments::Client::GatewayErrors::BankNotSupportedBySwitch,
CloudPayments::Client::GatewayErrors::ExpiredCard,
CloudPayments::Client::GatewayErrors::Invalid,
CloudPayments::Client::GatewayErrors::LostCard,
CloudPayments::Client::GatewayErrors::StolenCard,
CloudPayments::Client::GatewayErrors::ReferToCardIssuer => err
error! err, err.message, :fatal
logger.error'Не возможно выполнить оплату с помощью привязанной карты'.freeze
rescue CloudPayments::Client::ReasonedGatewayError => err
error! err, err.message, :fatal
raise err
rescue => err
error! err, "Ошибка рекурентного платежа: #{err.message}", :fatal
raise err
end
То есть заметьте, вот для этих ошибок нет смысла делать именованные классы:
CloudPayments::Client::GatewayErrors::AntiFraud,
CloudPayments::Client::GatewayErrors::BankNotSupportedBySwitch,
CloudPayments::Client::GatewayErrors::ExpiredCard,
CloudPayments::Client::GatewayErrors::Invalid,
CloudPayments::Client::GatewayErrors::LostCard,
CloudPayments::Client::GatewayErrors::StolenCard,
CloudPayments::Client::GatewayErrors::ReferToCardIssuer
не представляю себе какие должны быть требования, чтобы бизнес-логика отличалась в случае ошибки LostCard
от StolenCard
. Это все фатальные исключения одно типа (класса).
В тоже время есть исключения типа InsufficientFunds
, которые означают что транзакцию можно построить позже это особый случай, который приходится обрабатывать по-особому.
Так вот, я даже не знаю какие могут быть исключения которые можно повторить позже кроме InsufficientFunds. А есть ли такие еще?
CloudPayments::Client::GatewayErrors::BankNotSupportedBySwitch
В случай этой ошибки может можно повторить запрос позже?