Error en el correo electrónico de resumen de vista previa: NoMethodError (método `>=` no definido para nil:NilClass)

Hola, obtengo este error al previsualizar el correo electrónico de resumen en el nuevo Discourse:

NoMethodError (método `>=` no definido para nil:NilClass) /var/www/discourse/app/mailers/user_notifications.rb:227:in `digest'

Pila de seguimiento

/var/www/discourse/app/mailers/user_notifications.rb:227:in `digest'
actionpack-6.0.1/lib/abstract_controller/base.rb:196:in `process_action'
actionpack-6.0.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack-6.0.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack-6.0.1/lib/abstract_controller/base.rb:136:in `process'
actionmailer-6.0.1/lib/action_mailer/rescuable.rb:25:in `block in process'
actionmailer-6.0.1/lib/action_mailer/rescuable.rb:17:in `handle_exceptions'
actionmailer-6.0.1/lib/action_mailer/rescuable.rb:24:in `process'
actionview-6.0.1/lib/action_view/rendering.rb:39:in `process'
actionmailer-6.0.1/lib/action_mailer/base.rb:637:in `block in process'
activesupport-6.0.1/lib/active_support/notifications.rb:180:in `block in instrument'
activesupport-6.0.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport-6.0.1/lib/active_support/notifications.rb:180:in `instrument'
actionmailer-6.0.1/lib/action_mailer/base.rb:636:in `process'
actionmailer-6.0.1/lib/action_mailer/message_delivery.rb:123:in `block in processed_mailer'
actionmailer-6.0.1/lib/action_mailer/message_delivery.rb:122:in `tap'
actionmailer-6.0.1/lib/action_mailer/message_delivery.rb:122:in `processed_mailer'
actionmailer-6.0.1/lib/action_mailer/message_delivery.rb:29:in `__getobj__'
/usr/local/lib/ruby/2.6.0/delegate.rb:80:in `method_missing'
/var/www/discourse/lib/email/renderer.rb:18:in `html'
/var/www/discourse/app/controllers/admin/email_controller.rb:93:in `preview_digest'
actionpack-6.0.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack-6.0.1/lib/abstract_controller/base.rb:196:in `process_action'
actionpack-6.0.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack-6.0.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport-6.0.1/lib/active_support/callbacks.rb:135:in `run_callbacks'
actionpack-6.0.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack-6.0.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
activesupport-6.0.1/lib/active_support/notifications.rb:180:in `block in instrument'
activesupport-6.0.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport-6.0.1/lib/active_support/notifications.rb:180:in `instrument'
actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
actionpack-6.0.1/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
activerecord-6.0.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack-6.0.1/lib/abstract_controller/base.rb:136:in `process'
actionview-6.0.1/lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler-2.0.1/lib/mini_profiler/profiling_methods.rb:78:in `block in profile_method'
actionpack-6.0.1/lib/action_controller/metal.rb:191:in `dispatch'
actionpack-6.0.1/lib/action_controller/metal.rb:252:in `dispatch'
actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack-6.0.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `each'
actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
rack-2.0.8/lib/rack/tempfile_reaper.rb:15:in `call'
rack-2.0.8/lib/rack/conditional_get.rb:25:in `call'
rack-2.0.8/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:318:in `call'
rack-2.0.8/lib/rack/session/abstract/id.rb:259:in `context'
rack-2.0.8/lib/rack/session/abstract/id.rb:253:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/cookies.rb:648:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
logster-2.8.0/lib/logster/middleware/reporter.rb:43:in `call'
railties-6.0.1/lib/rails/rack/logger.rb:38:in `call_app'
railties-6.0.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:22:in `call'
rack-2.0.8/lib/rack/method_override.rb:22:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
rack-2.0.8/lib/rack/sendfile.rb:111:in `call'
actionpack-6.0.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
rack-mini-profiler-2.0.1/lib/mini_profiler/profiler.rb:200:in `call'
message_bus-2.2.4/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:172:in `call'
railties-6.0.1/lib/rails/engine.rb:526:in `call'
railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
rack-2.0.8/lib/rack/urlmap.rb:68:in `block in call'
rack-2.0.8/lib/rack/urlmap.rb:53:in `each'
rack-2.0.8/lib/rack/urlmap.rb:53:in `call'
unicorn-5.5.4/lib/unicorn/http_server.rb:605:in `process_client'
unicorn-5.5.4/lib/unicorn/http_server.rb:700:in `worker_loop'
unicorn-5.5.4/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
unicorn-5.5.4/lib/unicorn/http_server.rb:144:in `start'
unicorn-5.5.4/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

Se puede solucionar si el usuario establece un período de tiempo:

Resumen de actividad en Preferencias > Correos electrónicos > Resumen de actividad

¿Podemos reproducir esto @tshenry?

Intenté activar esto con una nueva instancia en nuestra infraestructura de alojamiento y un droplet DO nuevo, pero no pude reproducirlo.

¿Puedes dar más detalles, @zcuric? Sería genial tener una forma consistente de reproducir el error.

@tshenry

Por lo que recuerdo, los pasos fueron:

  1. Nueva instancia
  2. Importación de la configuración (a continuación, se eliminaron algunas de las configuraciones personales) desde la instancia de desarrollo a la nueva instancia
suggested_topics: '0'
post_menu: read|share|edit|bookmark|delete|flag|admin|reply
desktop_category_page_style: categories_only
fixed_category_positions: 'true'
fixed_category_positions_on_create: 'true'
enable_badges: 'false'
push_notifications_prompt: 'false'
login_required: 'true'
email_editable: 'false'
public_user_custom_fields: is_learning
enable_user_directory: 'false'
hide_user_profiles_from_public: 'true'
max_notifications_per_user: '10'
enable_group_directory: 'false'
title_prettify: 'false'
allow_uncategorized_topics: 'false'
enable_personal_messages: 'false'
enable_system_message_replies: 'false'
edit_history_visible_to_public: 'false'
max_reply_history: '4'
newuser_max_mentions_per_post: '10'
emoji_set: google
email_time_window_mins: '30'
email_accent_bg_color: F1F3F4
email_accent_fg_color: "#343F79"
email_link_color: "#343F79"
reply_by_email_enabled: 'true'
manual_polling_enabled: 'true'
pop3_polling_ssl: 'false'
pop3_polling_openssl_verify: 'false'
log_mail_processing_failures: 'true'
email_in: 'true'
email_in_min_trust: '0'
unsubscribe_via_email_footer: 'true'
theme_authorized_extensions: jpg|jpeg|png|woff|woff2|svg|eot|ttf|otf|gif|js|*
authorized_extensions: jpg|jpeg|png|gif|*
allow_uploaded_avatars: 'false'
restrict_letter_avatar_colors: 343F79
default_trust_level: '1'
allow_flagging_staff: 'false'
send_tl1_welcome_message: 'false'
trusted_users_can_edit_others: 'false'
detailed_404: 'true'
enable_flash_video_onebox: 'true'
auto_silence_fast_typers_on_first_post: 'false'
max_edits_per_day: '100'
max_topics_in_first_day: '10'
privacy_policy_url: "/t/about/6"
search_prefer_recent_posts: 'true'
new_version_emails: 'false'
educate_until_posts: '1'
disable_avatar_education_message: 'true'
show_create_topics_notice: 'false'
likes_notification_consolidation_window_mins: '1'
automatically_unpin_topics: 'false'
default_email_digest_frequency: '0'
default_email_mailing_list_mode: 'true'
default_other_like_notification_frequency: '3'
dashboard_general_tab_activity_metrics: page_view_total_reqs|visits|time_to_first_response|user_to_user_private_messages_with_replies
discourse_narrative_bot_enabled: 'false'
disable_discourse_narrative_bot_welcome_post: 'true'
discourse_narrative_bot_welcome_post_delay: '1'
allow_solved_on_all_topics: 'true
  1. Ocurrió este error.

Bueno, ¡esa fue una complicación! Finalmente pude reproducirlo en un sitio recién instalado de forma autónoma importando la configuración del sitio (eso parece ser la clave aquí). Creo que en este punto he reducido el problema a una configuración específica. Aquí está la reproducción completa que me hizo encontrarlo:

  1. Sigue nuestra Guía de instalación hasta llegar al paso de creación del administrador (no crees un administrador todavía). Entra a la aplicación:

    ./launcher enter app
    

    Crea un archivo settings.yml en /var/www/discourse con la siguiente configuración:

    ---
    default_email_digest_frequency: '0'
    
  2. Ejecuta

    rake site_settings:import < settings.yml
    

    Deberías ver que menciona Changed default_email_digest_frequency FROM: 10080 TO: 0.

  3. Crea un administrador a través de la interfaz de usuario, omite el asistente de configuración y ve directamente a la vista previa del resumen en la configuración del sitio.

  4. Verás esto y las entradas asociadas en /logs:


Así es como solucioné manualmente la situación desde la consola de Rails:

# Obtener las opciones de usuario del primer y único usuario humano
user_op = User.find(1).user_option

# Observa que está establecido en nil
user_op.digest_after_minutes
=> nil

# Establecerlo en una opción válida. Elegí 0
user_op.digest_after_minutes = 0
user_op.save!

Después de eso, la vista previa del resumen funcionará sin problemas.


No estoy seguro inmediatamente cuál es la solución. Lo siguiente me hizo sospechar, ya que hay una prueba mayor que 0 y nuestro valor de importación es 0:

@codinghorror, ¿crees que este es un caso tan extremo que queramos esperar a la regla de los tres? ¿O prefieres que yo o alguien más investigue una solución?

¿Probablemente una solución sencilla? ¿Quizás @sam pueda asignarlo para el lunes?