Filtres de sujet personnalisés : les paramètres URL n'atteignent pas `TopicQuery.options`

Rapport d’avancement jusqu’à présent :

  1. Confirmation que les méthodes de liste blanche statiques TopicQuery telles que add_custom_param_handler ou extra_options_whitelist ne sont pas disponibles en tant que méthodes de classe dans ma version de Discourse, donc ces approches ont été abandonnées.

  2. Mise en œuvre d’un patch pour ListController#build_topic_list_options afin d’injecter mes paramètres d’URL personnalisés (par exemple, market_item_statuses, market_price_min) dans la hache opts avant que TopicQuery.new ne soit appelé.

  3. Cette partie fonctionne maintenant ! Lorsque je fais une requête comme /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available, mes logs serveur confirment l’injection :

    [TecencMarket_ListControllerExt_BuildOptsV3] Injecté dans opts : market_item_statuses = Available
    

    Donc, TopicQuery.new(user, opts) reçoit maintenant opts contenant mes paramètres personnalisés.

Point bloquant actuel : erreur 500 & blocage du filtre non atteint

Malgré le fait que les paramètres soient maintenant correctement passés à l’initialiseur de TopicQuery, je reçois toujours une erreur 500 Internal Server Error lorsque la requête inclut ces paramètres de marché personnalisés.

Pour isoler cela, j’ai simplifié mon bloc TopicQuery.add_custom_filter(:"tecenc_market_filters") au maximum.

# plugin.rb - Bloc de filtre personnalisé simplifié actuel
if ::TopicQuery.respond_to?(:add_custom_filter)
  ::TopicQuery.add_custom_filter(:"tecenc_market_filters") do |topics, topic_query|
    relation_orig = topics 
    opts = topic_query.options
    log_prefix_query = "[TecencMarket_SimplifiedFilter_V1.1_Test]" # Mon préfixe de débogage

    Rails.logger.info "#{log_prefix_query} Options reçues par TopicQuery : #{opts.inspect}"

    if opts[:market_item_statuses].present?
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' EST PRÉSENT dans opts : #{opts[:market_item_statuses]}"
    else
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' N'EST PAS PRÉSENT dans opts."
    end
    
    Rails.logger.info "#{log_prefix_query} Retourne la relation de sujets originale."
    relation_orig # Retour implicite
  end
  Rails.logger.info "[TecencMarket] Filtre personnalisé SIMPLIFIÉ (V1.1_Test) appliqué."
end

Observations avec ce filtre simplifié :

  • Requêtes sans mon paramètre de filtre personnalisé (par exemple, /c/market/5/l/latest.json?filter=default) :

    • Le bloc de filtre simplifié enregistre correctement :

      [TecencMarket_SimplifiedFilter_V1.1_Test] Options reçues par TopicQuery : {:category=>5, :filter=>"default", ...}
      [TecencMarket_SimplifiedFilter_V1.1_Test] 'market_item_statuses' N'EST PAS PRÉSENT dans opts.
      [TecencMarket_SimplifiedFilter_V1.1_Test] Retourne la relation de sujets originale.
      
    • La page se charge avec un 200 OK.

  • Requêtes avec mon paramètre de filtre personnalisé (par exemple, /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available) :

    • L’entrée de log du patch du ListController apparaît : [TecencMarket_ListControllerExt_BuildOptsV3] Injecté dans opts : market_item_statuses = Available

    {“content”: "* Une Completed 500 Internal Server Error in ...ms se produit immédiatement après.

    • De manière cruciale, AUCUN journal provenant de la zone de filtrage simplifiée (pas de lignes [TecencMarket_SimplifiedFilter_V1.1_Test]...) n’apparaît pour cette requête échouée.

Cela indique que l’erreur 500 se produit après que TopicQuery a été initialisé avec le hash opts (qui contient désormais mes paramètres personnalisés), mais avant ou juste au moment où le mécanisme central de Discourse TopicQuery#apply_custom_filters tente d’exécuter mon bloc de filtre enregistré (et maintenant extrêmement simple).

J’ai du mal à isoler l’exception Ruby spécifique et la trace complète dans development.log qui précèdent immédiatement la ligne “Completed 500…” pour les requêtes échouées (les extraits de journal que j’ai rassemblés montrent la ligne 500 elle-même, mais pas le message d’erreur détaillé juste avant).

Question de suivi :

Étant donné que :

  1. Les paramètres personnalisés sont maintenant injectés avec succès dans TopicQuery.options par la correction du ListController.

  2. Une erreur 500 se produit lorsque ces paramètres personnalisés sont présents dans opts.

  3. Cette erreur 500 se produit avant même qu’un bloc de filtre personnalisé extrêmement simplifié (qui ne fait que enregistrer et renvoyer la relation originale) ne commence à exécuter sa première ligne de code pour la requête avec ces paramètres.

  4. Cela concerne Discourse 3.5.0.beta3-dev.

Qu’est-ce qui pourrait faire que TopicQuery lui-même, ou sa méthode apply_custom_filters, plante avant d’appeler un bloc de filtre personnalisé enregistré, spécifiquement lorsque le hash options contient ces clés spécifiques au plugin ? Le LocalJumpError que nous soupçonnions pourrait-il encore être pertinent à un niveau inférieur dans la gestion de l’itération ou de l’appel des blocs de filtre par apply_custom_filters, même si mon bloc simplifié est simplement un retour implicite ?

Tout conseil sur ce qu’il faut vérifier ensuite dans le comportement de TopicQuery avec ces options personnalisées, ou des astuces pour obtenir de manière robuste la trace complète pour l’erreur 500 dans ce scénario, seraient très utiles."}