Ошибка экспорта архива данных пользователя: undefined method 'url' for an instance of DiscourseDataExplorer::QueryGroup

Полное раскрытие информации: я использовал ask.discourse для составления этого отчёта об ошибке после разговора. Также я знаю, что у меня не обновлённая версия, но я хотел опубликовать это, пока всё было свежо в памяти.

Мне удалось воспроизвести проблему на двух разных пользовательских аккаунтах.

Краткое описание

Запрос архива пользовательских данных (Настройки → Экспорт ваших данных → Запросить архив) завершается ошибкой для пользователей, которые добавили в закладки отчёт группы Data Explorer. Фоновая задача Jobs::ExportUserArchive падает при генерации CSV-файла закладок, поэтому экспорт никогда не завершается, и ссылка для скачивания не отправляется.

Окружение

  • Версия Discourse: 2026.8.0-latest.1
  • Data Explorer: входит в состав ядра (версия следует за версией ядра)
  • Самостоятельный хостинг / хостинг: самостоятельный хостинг
  • Стек Ruby/Rails согласно backtrace: activemodel/activerecord 8.0.5.1, Sidekiq 7.3.10

Шаги для воспроизведения

  1. От имени администратора создайте запрос Data Explorer и предоставьте доступ группе.
  2. На вкладке Отчёты группы нажмите Добавить в закладки для запроса, чтобы он стал отчётом группы в закладках.
  3. От имени того же пользователя перейдите в Настройки → Экспорт ваших данных → Запросить архив.
  4. Проследите за сбоем задачи (проверьте Администрирование → Журналы или логи Sidekiq).

Ожидаемое поведение

Архив пользователя должен быть сгенерирован, и пользователь должен получить ссылку для скачивания, включая свои закладки.

Фактическое поведение

Задача экспорта вызывает исключение, и архивация завершается ошибкой. Backtrace показывает, что сбой происходит в bookmarks_export, где задача вызывает .url для объекта из закладок:

Job exception: undefined method 'url' for an instance of DiscourseDataExplorer::QueryGroup

Backtrace (сокращён до соответствующих кадров):

activemodel-8.0.5.1/lib/active_model/attribute_methods.rb:512:in 'ActiveModel::AttributeMethods#method_missing'
activerecord-8.0.5.1/lib/active_record/attribute_methods.rb:495:in 'ActiveRecord::AttributeMethods#method_missing'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:325:in 'block in Jobs::ExportUserArchive#bookmarks_export'
activerecord-8.0.5.1/lib/active_record/relation/delegation.rb:101:in 'Array#each'
activerecord-8.0.5.1/lib/active_record/relation/delegation.rb:101:in 'ActiveRecord::Delegation#each'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:319:in 'Jobs::ExportUserArchive#bookmarks_export'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:170:in 'Kernel#public_send'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:170:in 'block (2 levels) in Jobs::ExportUserArchive#execute'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:168:in 'block in Jobs::ExportUserArchive#execute'

Анализ

Закладки являются полиморфными. Задача экспорта вызывает bookmarkable.url, что работает для основных типов объектов, которые можно добавлять в закладки (Topic, Post), но DiscourseDataExplorer::QueryGroup не реализует метод url, поэтому задача вызывает NoMethodError на первой такой закладке.

Похоже, что Data Explorer регистрирует группы запросов как объекты, которые можно добавлять в закладки (через кнопку «Добавить в закладки» в отчёте группы), но модели не хватает метода url (или основной задаче экспорта нужна проверка для типов объектов, которые не предоставляют этот метод).

Предлагаемое исправление

Либо реализуйте метод url для DiscourseDataExplorer::QueryGroup, либо сделайте bookmarks_export в ядре более устойчивым к ошибкам (например, bookmarkable.respond_to?(:url) / rescue для каждой строки), чтобы один неподдерживаемый тип объекта не мог прервать весь экспорт.

Обходной путь

Удаление проблемных закладок (строк в таблице bookmarks, где bookmarkable_type = 'DiscourseDataExplorer::QueryGroup' для затронутого пользователя) позволяет экспорту завершиться.