This looks like a Bug, but I don’t know what’s going on.
A bunch of users get a 500 error trying to load /s/user/subscriptions/ (when visiting /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
Maybe I’m missing something, but /s/<username>/subscriptions/ isn’t a route in the plugin is it?
So far when I visit /my/billing/subscriptions locally and on a production site it redirect correctly to /u/<username>/billing/subscriptions and I’m not getting a 500 error.
It pulls from that endpoint. And on this server, with some users, I get a 500 error (I should have included a screenshot, I think). I think it’s been happening for a while? They got me on board to upgrade, which I did, and then they reported this error, but it seems that they were hoping that the upgrade was going to resolve it (at least the upgrade didn’t break it?).
Zero. My best guess is that something happened at some point in the past and now it’s getting a nil from somewhere instead of an array? But I’ve looked at the code and don’t see anywhere that’s not testing for nil before accessing an array.
I’m assuming it’s only for this one site? You aren’t seeing this on other sites? Yes, there is a “bug” where we shouldn’t return a 500, but there is likely some “bad” data somewhere like a missing plan or something. Maybe it got removed in stripe and never got updated in the plugin db.
Can you run these rails console commands to help me debug?
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 # note how many subscriptions they have
subscription = subs.first # change this and run the below lines for each 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
I’m thinking either plans or plan will return nil, but that will help us narrow down where the issue is. Could you let me know how many subscriptions they have and if there are any missing plans for them?
Likely a code fix I’ll make is to just not return any subscriptions for these users if there is an error, but if they actually have a subscription that isn’t really solving the issue. Maybe I’ll have it return an error that says something like a subscription has been found but there is an error loading the plan details for it, please reach out to an admin for help.
There are 100 plans (so probably more than that)-- maybe this is the problem? (I tried with limit: 1000 but that didn’t change anything; I guess that’s a Stripe API limit?)
So maybe if there are >100 plans it fails? Oh, and the users for whom it’s not failing, are on plans that are in the first 100.
# Get the last item's ID
last_price_id = plans.data.last.id
# Get the next 100
next_plans = ::Stripe::Price.list(
expand: ['data.product'],
limit: 100,
starting_after: last_price_id
)