Isto parece um Bug, mas não sei o que está acontecendo.
Vários usuários recebem um erro 500 ao tentar carregar /s/user/subscriptions/ (ao visitar /my/billing/subscriptions.
NoMethodError (undefined method `[]' for nil) app/controllers/application_controller.rb:427:in `block in with_resolved_locale' app/controllers/application_controller.rb:427:in `with_resolved_locale' l
Talvez eu esteja perdendo alguma coisa, mas /s/<username>/subscriptions/ não é uma rota no plugin, é?
Até agora, quando visito /my/billing/subscriptions localmente e em um site de produção, ele redireciona corretamente para /u/<username>/billing/subscriptions e eu não recebo um erro 500.
Alguma outra pista sobre como posso reproduzir isso?
Ele puxa desse endpoint. E neste servidor, com alguns usuários, recebo um erro 500 (acho que deveria ter incluído uma captura de tela). Acho que isso está acontecendo há algum tempo? Eles me contrataram para fazer o upgrade, o que eu fiz, e então eles relataram esse erro, mas parece que eles esperavam que o upgrade fosse resolvê-lo (pelo menos o upgrade não o quebrou?).
Zero. Minha melhor suposição é que algo aconteceu em algum momento no passado e agora está recebendo um nil de algum lugar em vez de um array? Mas eu olhei o código e não vejo nenhum lugar que não esteja testando para nil antes de acessar um array.
Estou assumindo que é apenas para este site? Você não está vendo isso em outros sites? Sim, existe um “bug” onde não deveríamos retornar um 500, mas provavelmente há alguns dados “ruins” em algum lugar, como um plano ausente ou algo assim. Talvez tenha sido removido no Stripe e nunca tenha sido atualizado no banco de dados do plugin.
Você pode executar estes comandos do console Rails para me ajudar a depurar?
Stripe.api_key = SiteSetting.discourse_subscriptions_secret_key
user = User.find_by(username: 'xxx')
customer = DiscourseSubscriptions::Customer.find_by(user_id: user.id)
subs = ::Stripe::Subscription.list(customer: stripe_customer_id, status: 'all')[:data]
subs.count # observe quantos assinaturas eles têm
subscription = subs.first # mude isso e execute as linhas abaixo para cada sub
price_id = subscription[:items][:data].first[:price][:id]
plans = ::Stripe::Price.list(expand: ['data.product'], limit: 100)
plan = plans[:data].find { |p| p[:id] == price_id }
plan
Estou pensando que ou plans ou plan retornarão nil, mas isso nos ajudará a identificar onde está o problema. Você poderia me dizer quantas assinaturas eles têm e se há planos ausentes para eles?
Provavelmente uma correção de código que farei é simplesmente não retornar nenhuma assinatura para esses usuários se houver um erro, mas se eles realmente tiverem uma assinatura, isso não resolverá o problema. Talvez eu faça com que retorne um erro dizendo algo como “uma assinatura foi encontrada, mas há um erro ao carregar os detalhes do plano para ela, entre em contato com um administrador para obter ajuda”.
Existem 100 planos (então provavelmente mais do que isso) - talvez esse seja o problema? (Tentei com limit: 1000, mas isso não mudou nada; acho que esse é um limite da API do Stripe?)
Então, talvez se houver >100 planos, falhe? Ah, e os usuários para os quais não está falhando, estão em planos que estão nos primeiros 100.
# Pega o ID do último item
last_price_id = plans.data.last.id
# Pega os próximos 100
next_plans = ::Stripe::Price.list(
expand: ['data.product'],
limit: 100,
starting_after: last_price_id
)