Problema con errore 500 nelle iscrizioni

Questo sembra un Bug, ma non so cosa stia succedendo.

Un gruppo di utenti riceve un errore 500 tentando di caricare /s/user/subscriptions/ (quando visita /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

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/content_security_policy/middleware.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'

Speravo che fosse un caso isolato, dato che non sembra essere un problema per tutti gli utenti. Non riesco a trovare uno schema.

Posso fare questo:

 user=User.find_by_username 'xxx'
 DiscourseSubscriptions::Customer.find_by(user_id: user.id)

e funziona.

Non sono sicuro di dove cercare ora.

1 Mi Piace

Forse mi sfugge qualcosa, ma /s/<username>/subscriptions/ non è un percorso nel plugin, vero?

Finora, quando visito /my/billing/subscriptions localmente e su un sito di produzione, viene reindirizzato correttamente a /u/<username>/billing/subscriptions e non ricevo un errore 500.

Qualche altro indizio su come posso riprodurre questo problema?

Grazie per il tuo aiuto!

Prende da quell’endpoint. E su questo server, con alcuni utenti, ottengo un errore 500 (penso che avrei dovuto includere uno screenshot). Credo che succeda da un po’? Mi hanno assunto per fare un aggiornamento, cosa che ho fatto, e poi hanno segnalato questo errore, ma sembra che sperassero che l’aggiornamento lo risolvesse (almeno l’aggiornamento non l’ha rotto?).

Zero. La mia migliore ipotesi è che sia successo qualcosa in passato e ora stia ricevendo un nil da qualche parte invece di un array? Ma ho guardato il codice e non vedo nessun punto in cui non venga testato il nil prima di accedere a un array.

1 Mi Piace

Presumo che sia solo per questo sito? Non lo vedi su altri siti? Sì, c’è un “bug” per cui non dovremmo restituire un 500, ma probabilmente ci sono dei dati “cattivi” da qualche parte, come un piano mancante o qualcosa del genere. Forse è stato rimosso in Stripe e non è mai stato aggiornato nel database del plugin.

Puoi eseguire questi comandi da console Rails per aiutarmi a fare il 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 # nota quante sottoscrizioni hanno
subscription = subs.first # cambia questo ed esegui le righe sottostanti per ogni sottoscrizione
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

Penso che o plans o plan restituiranno nil, ma questo ci aiuterà a restringere il campo del problema. Potresti dirmi quante sottoscrizioni hanno e se mancano dei piani per loro?

Probabilmente una correzione del codice che farò sarà semplicemente quella di non restituire alcuna sottoscrizione per questi utenti in caso di errore, ma se hanno effettivamente una sottoscrizione che non risolve il problema. Forse restituirò un errore che dice qualcosa come “è stata trovata una sottoscrizione ma c’è un errore nel caricamento dei dettagli del piano per essa, si prega di contattare un amministratore per assistenza”.

Fantastico. Grazie!

C’era un abbonamento.

Una correzione al tuo codice:

subs = ::Stripe::Subscription.list(customer: customer.stripe_customer_id, status: 'all')[:data]

Ci sono 100 piani (quindi probabilmente di più) - forse questo è il problema? (Ho provato con limit: 1000 ma non è cambiato nulla; immagino che sia un limite dell’API di Stripe?)

Quindi forse se ci sono >100 piani fallisce? Oh, e gli utenti per i quali non fallisce, sono su piani che sono nei primi 100.

discourse(prod)> plan = plans[:data].find { |p| p[:id] == price_id }
discourse(prod)>
=> nil

EDIT:

Sì. Se faccio questo:

# Ottieni l'ID dell'ultimo elemento
last_price_id = plans.data.last.id

# Ottieni i successivi 100
next_plans = ::Stripe::Price.list(
  expand: ['data.product'],
  limit: 100,
  starting_after: last_price_id
)

allora

discourse(prod)> next_plans[:data].find { |p| p[:id] == price_id }

trova quello che sta cercando.

EDIT DI NUOVO: next_plans.count == 8. Ho suggerito che eliminassero 10 piani.

1 Mi Piace

Grazie per tutte le informazioni, sono utili.

Sì, questo risolverebbe il problema per una correzione non di codice. Sembra buono se hanno molti piani obsoleti.

Aggiungerò anche una paginazione in modo da poterli recuperare tutti nel caso in cui ci imbattiamo di nuovo in questo problema.

1 Mi Piace

Ecco la correzione per questo:

1 Mi Piace

Questo argomento è stato chiuso automaticamente dopo 4 giorni. Non sono più permesse nuove risposte.