The discussion revolves around a 500 error issue with subscriptions on a Discourse site. pfaffman initially reports the issue, stating that some users encounter a 500 error when visiting /my/billing/subscriptions. The error is caused by a NoMethodError due to an undefined method [] for nil.
blake investigates the issue and suggests that the problem might be related to “bad” data, such as a missing plan. blake provides rails console commands to help debug the issue, which reveals that the problem occurs when there are more than 100 plans, causing the Stripe::Price.list method to return nil.
pfaffman confirms this theory and suggests deleting unnecessary plans as a temporary fix. blake agrees and decides to add pagination to the Stripe::Price.list method to prevent similar issues in the future. The fix is implemented in this pull request.
This looks like a Contribute > 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
)