Enlaces a subidas rotas en temas provocan errores 500 con 2.5.0

Dirijo un sitio de Discourse y quiero empezar diciendo lo mucho que amo este software. Gracias a todo el equipo por el gran trabajo, es una herramienta increíble.

Después de una actualización a la versión 2.5.0, tuve grandes problemas. Aquí está el resumen y la solución temporal que apliqué. Quizás esto conduzca a una corrección mucho mejor en futuras versiones.

Algunos de los temas que tenemos en nuestra base de datos contienen subidas rotas. Usamos la función de “Subidas a S3” y, por error, eliminamos el bucket. Sí, fue algo muy tonto, pero bueno, lo hicimos. El resultado fue que se perdieron todas las imágenes de los temas.

Excepto por el hecho de que habíamos perdido muchas imágenes, todo estaba bien: Discourse mostraba enlaces rotos a imágenes que ya no existían, pero todo funcionaba correctamente.

Pero cuando quisimos actualizar a la versión 2.5.0, todo se volvió loco: todos los usuarios conectados recibían errores 500, mientras que los visitantes anónimos podían ver el sitio web.

Después de investigar, me di cuenta de que Discourse fallaba con errores de “Archivo no encontrado”. Parece que intentaba descargarlos. Tuve que forzar el método local? a true en /var/www/discourse/app/models/upload.rb y eso solucionó el problema, pero me preocupa un poco las próximas actualizaciones…

Esto es claramente algo nuevo, ya que las actualizaciones anteriores no causaron problemas.

Por cierto, ¿hay algún método que pueda seguir para eliminar todos los enlaces a imágenes muertas que tenemos en nuestros temas?

Gracias.

Obtuvimos el comportamiento contrario: el usuario conectado funciona bien, pero los que no han iniciado sesión no pueden conectarse y reciben un error 500.

¿Puedes compartir un rastreo completo de ese error?
Revisa tu página /logs.

Esto me suena mucho a un plugin incompatible. ¿Qué plugins no oficiales estás ejecutando? ¿Has intentado reconstruir sin ellos?

Claro, en mi log/production.log, apareció la siguiente excepción (cuando Discourse intentaba acceder al bucket de S3 vacío (que volví a crear, con la esperanza de que solucionara el problema)).

Iniciado GET “/” para 86.246.127.170 el 2020-05-16 14:29:06 +0000
Procesando por ListController#latest como HTML
Creando ámbito :open. Sobrescribiendo el método existente Poll.open.
Finalizado 500 Internal Server Error en 3638ms (ActiveRecord: 0.0ms | Asignaciones: 135090)
NoMethodError (método path no definido para nil:NilClass)
/var/www/discourse/lib/file_store/base_store.rb:150:in `cache_file’

Espero que esto ayude.

Gracias, podría ser eso. De hecho tengo instalados dos complementos: Discourse Adsense y discourse-chat-integration. Intentaré una reconstrucción sin ellos.

Puedo confirmar que esto no es causado por un plugin: reproduje el mismo error con una instalación limpia + una restauración de mi última copia de seguridad y sin plugins instalados, excepto docker_manager.

La primera traza de pila que obtuve es:

Completado 500 Internal Server Error en 4169ms (ActiveRecord: 0.0ms | Asignaciones: 72058)
NoMethodError (método path no definido para nil:NilClass)
/var/www/discourse/lib/file_store/base_store.rb:150:in `cache_file’

Lo parché de la siguiente manera:

def cache_file(file, filename)
path = get_cache_path_for(filename)
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)

  if file.nil?
    return
  end

  FileUtils.cp(file.path, path)

Lo cual llevó a un segundo error (el que mencioné en mi publicación inicial):

Inicio de GET “/” para 86.246.127.170 el 2020-05-18 07:37:40 +0000
Procesando por CategoriesController#index como HTML
Completado 500 Internal Server Error en 4342ms (ActiveRecord: 0.0ms | Asignaciones: 60478)
NoMethodError (método path no definido para nil:NilClass)
/var/www/discourse/app/models/upload.rb:193:in `fix_dimensions!’

Lo cual corregí forzando local? a true:

def local?
return true
!(url =~ /^(https?:)?///)
end

¿Has movido tus archivos hacia o desde S3 en algún momento?

Sí, lo hice. Pero luego, el bucket se eliminó. Y volví al almacenamiento local (con enlaces de imágenes rotos en temas anteriores, obviamente).

Creo que la mejor opción aquí es que borres definitivamente todas las filas de carga defectuosas de tu base de datos.

Si no tienes ninguna carga, no la mantengas ahí.

Sí, estoy de acuerdo, pero tengo miedo de ejecutar un “nuke” así manualmente en la base de datos. ¿Tienes alguna sugerencia para hacerlo de forma “adecuada”? ¿O debería hacerlo realmente “manualmente”?

Además, tengo la sensación de que este cambio de comportamiento en Discourse es un poco preocupante. Significa, por lo que puedo ver, que si en algún momento hay un enlace a una imagen rota en algún lugar, la aplicación se va a bloquear.

Antes no era así. Sugiero hacerlo más robusto en situaciones como esta.

Muy parecido a lo que tenemos:

Lo “arreglé” volviendo a ejecutar la configuración del asistente.

Sí, esto parece ser el mismo problema. @sukria, si actualizas a la versión más reciente de tests-passed, he añadido una corrección que hace el proceso más robusto frente a subidas fallidas (aunque, aún deberías intentar limpiar las referencias a las subidas fallidas).

También me interesa una forma sencilla de limpiar esos enlaces rotos también :wink:

Gracias @david, confirmo que una reconstrucción fresca contra tests-passed funcionó sin problemas. ¡Gracias!
¿Alguna sugerencia sobre una forma adecuada y sencilla de eliminar esos enlaces rotos en los temas?