Problema con error 500 en las suscripciones

Esto parece un Bug, pero no sé qué está pasando.

Un montón de usuarios reciben un error 500 al intentar cargar /s/user/subscriptions/ (al 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

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'

Esperaba que fuera una casualidad, ya que no parece estar roto para todos los usuarios. Sin embargo, no encuentro un patrón.

Puedo hacer esto:

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

y eso funciona.

No estoy seguro de dónde mirar a continuación.

1 me gusta

Quizás me estoy perdiendo algo, pero /s/<username>/subscriptions/ no es una ruta en el plugin, ¿verdad?

Hasta ahora, cuando visito /my/billing/subscriptions localmente y en un sitio de producción, se redirige correctamente a /u/<username>/billing/subscriptions y no obtengo un error 500.

¿Alguna otra pista sobre cómo puedo reproducir esto?

¡Gracias por tu ayuda!

Se extrae de ese endpoint. Y en este servidor, con algunos usuarios, obtengo un error 500 (creo que debería haber incluido una captura de pantalla). ¿Creo que ha estado sucediendo por un tiempo? Me contrataron para actualizar, lo cual hice, y luego informaron este error, pero parece que esperaban que la actualización lo resolviera (¿al menos la actualización no lo rompió?).

Cero. Mi mejor suposición es que algo sucedió en algún momento en el pasado y ahora está obteniendo un nil de algún lugar en lugar de un array. Pero he mirado el código y no veo ningún lugar que no esté comprobando si es nil antes de acceder a un array.

1 me gusta

¿Supongo que es solo para este sitio? ¿No lo ves en otros sitios? Sí, hay un “error” por el cual no deberíamos devolver un 500, pero es probable que haya algunos datos “malos” en alguna parte, como un plan faltante o algo así. Quizás se eliminó en Stripe y nunca se actualizó en la base de datos del plugin.

¿Puedes ejecutar estos comandos de la consola de Rails para ayudarme 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 # cuántas suscripciones tienen
subscription = subs.first # cambia esto y ejecuta las siguientes líneas 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

Creo que planes o plan devolverán nulo, pero eso nos ayudará a reducir dónde está el problema. ¿Podrías decirme cuántas suscripciones tienen y si faltan planes para ellos?

Probablemente una solución de código que haré será simplemente no devolver ninguna suscripción para estos usuarios si hay un error, pero si realmente tienen una suscripción, eso no resuelve el problema. Quizás haga que devuelva un error que diga algo como que se ha encontrado una suscripción pero hay un error al cargar los detalles del plan para ella, por favor contacta a un administrador para obtener ayuda.

Genial. ¡Gracias!

Hubo una suscripción.

Una corrección en tu código:

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

Hay 100 planes (así que probablemente más que eso), ¿quizás este sea el problema? (Intenté con limit: 1000 pero eso no cambió nada; supongo que es un límite de la API de Stripe)

Entonces, ¿quizás si hay >100 planes falla? Ah, y los usuarios para quienes no falla, están en planes que están entre los primeros 100.

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

EDITAR:

Sí. Si hago esto:

# Obtener el ID del último elemento
last_price_id = plans.data.last.id

# Obtener los siguientes 100
next_plans = ::Stripe::Price.list(
  expand: ['data.product'],
  limit: 100,
  starting_after: last_price_id
)

entonces

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

encuentra lo que busca.

EDITAR DE NUEVO: next_plans.count == 8. Sugerí que eliminaran 10 planes.

1 me gusta

Gracias por toda la información, es útil.

Sí, eso solucionaría el problema para una solución que no sea de código. Suena bien si tienen muchos planes obsoletos.

También añadiré algo de paginación para que podamos obtenerlos todos en caso de que volvamos a encontrarnos con esto.

1 me gusta

Aquí está la solución para eso:

1 me gusta

Este tema se cerró automáticamente después de 4 días. Ya no se permiten nuevas respuestas.