pfaffman
(Jay Pfaffman)
1
这看起来像个 Bug,但我不知道是怎么回事。
很多用户在访问 /my/billing/subscriptions 时会遇到 500 错误,无法加载 /s/user/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
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'
lib/middleware/omniauth_bypass_middleware.rb:35:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
lib/middleware/anonymous_cache.rb:410:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
lib/middleware/default_headers.rb:13:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/processing_request.rb:12:in `call'
lib/middleware/request_tracker.rb:385:in `call'
我希望这只是个巧合,因为它似乎并非影响所有用户。我找不到任何规律。
我可以这样做:
user=User.find_by_username 'xxx'
DiscourseSubscriptions::Customer.find_by(user_id: user.id)
这是可以正常工作的。
我不确定接下来该看哪里。
1 个赞
blake
(Blake Erickson)
4
也许我遗漏了什么,但是 /s/<username>/subscriptions/ 并不是插件中的路由,对吧?
到目前为止,我在本地和生产站点上访问 /my/billing/subscriptions 时,它都会正确重定向到 /u/<username>/billing/subscriptions,并且我没有收到 500 错误。
还有其他关于我如何重现此问题的线索吗?
pfaffman
(Jay Pfaffman)
5
感谢您的帮助!
它会从该端点拉取。在此服务器上,对于某些用户,我会收到 500 错误(我认为我应该附上截图)。我认为这种情况已经发生了一段时间了?他们让我加入升级,我照做了,然后他们报告了这个错误,但似乎他们希望升级能够解决它(至少升级没有破坏它?)。
零。我最好的猜测是,过去某个时候发生了某些事情,现在它从某个地方得到了一个 nil 而不是一个数组?但我已经查看了代码,没有看到任何地方在访问数组之前没有检查 nil。
1 个赞
blake
(Blake Erickson)
6
我猜这只是针对这个网站?你在其他网站上没有看到这个吗?是的,有一个“bug”,我们不应该返回 500,但可能有一些“坏”数据,比如缺少计划或类似的东西。也许它在 Stripe 中被删除了,但从未在插件数据库中更新。
你能运行这些 rails 控制台命令来帮助我调试吗?
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 # 注意他们有多少订阅
subscription = subs.first # 更改此项并为每个订阅运行以下行
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
我猜计划或 plan 会返回 nil,但这将帮助我们缩小问题的范围。你能告诉我他们有多少订阅以及是否有任何计划丢失吗?
很可能是一个代码修复,我将只为这些用户返回任何订阅(如果有错误),但如果他们实际上有一个订阅,那并没有真正解决问题。也许我会让它返回一个错误,比如“已找到订阅,但加载其计划详细信息时出错,请联系管理员寻求帮助”。
pfaffman
(Jay Pfaffman)
7
好的。谢谢!
有一个订阅。
您的代码有一个修复:
subs = ::Stripe::Subscription.list(customer: customer.stripe_customer_id, status: 'all')[:data]
有 100 个计划(所以可能不止这些)——这可能是问题所在吗?(我尝试了 limit: 1000 但没有改变任何东西;我猜那是 Stripe API 的限制?)
所以也许当计划数 > 100 时它会失败?哦,而且那些没有失败的用户,他们的计划都在前 100 个之内。
discourse(prod)> plan = plans[:data].find { |p| p[:id] == price_id }
discourse(prod)>
=> nil
编辑:
是的。如果我这样做:
# 获取最后一个项目的 ID
last_price_id = plans.data.last.id
# 获取接下来的 100 个
next_plans = ::Stripe::Price.list(
expand: ['data.product'],
limit: 100,
starting_after: last_price_id
)
然后
discourse(prod)> next_plans[:data].find { |p| p[:id] == price_id }
找到了它正在寻找的东西。
再次编辑:next_plans.count == 8。我建议他们删除 10 个计划。
1 个赞
blake
(Blake Erickson)
8
感谢所有信息,这很有帮助。
是的,这可以解决非代码修复的问题。如果他们有很多过时的计划,听起来不错。
我也会添加一些分页,以便我们以后遇到这种情况时可以全部获取。
1 个赞