自定义主题过滤器:URL参数未传递到 `TopicQuery.options`

{“progress_report”: “到目前为止的进展:\n\n1. 确认在我的 Discourse 版本中,像 add_custom_param_handler 或 extra_options_whitelist 这样的静态 TopicQuery 白名单方法不可用,因此放弃了这些方法。\n\n2. 对 ListController#build_topic_list_options 进行了补丁,以在调用 TopicQuery.new 之前,将我自定义的 URL 参数(例如 market_item_statuses,market_price_min)注入到 opts 哈希中。\n\n3. 这部分现在工作正常! 当我发出像 /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available 这样的请求时,我的服务器日志确认了注入:\n\n \n [TecencMarket_ListControllerExt_BuildOptsV3] 注入到 opts 中:market_item_statuses = Available\n \n 所以,TopicQuery.new(user, opts) 现在接收到的 opts 包含我自定义的参数。\n\n当前遇到的问题: 500 错误 & 过滤器块未执行\n\n虽然参数现在被正确传递到 TopicQuery 的初始化器,但我仍然在请求包含这些自定义市场参数时遇到 500 内部服务器错误。\n\n为排查问题,我简化我的 TopicQuery.add_custom_filter(:"tecenc_market_filters") 块到最基本的形式。\n\nruby\n# plugin.rb - 当前简化的自定义过滤器块\nif ::TopicQuery.respond_to?(:add_custom_filter)\n ::TopicQuery.add_custom_filter(:"tecenc_market_filters") do |topics, topic_query| original_topics_relation = topics \n opts = topic_query.options\n log_prefix_query = "[TecencMarket_SimplifiedFilter_V1.1_Test]" # 我的调试前缀\n\n Rails.logger.info "#{log_prefix_query} 通过 TopicQuery 接收的 Opts:#{opts.inspect}"\n\n if opts[:market_item_statuses].present?\n Rails.logger.info "#{log_prefix_query} 'market_item_statuses' 存在于 opts 中:#{opts[:market_item_statuses]}"\n else\n Rails.logger.info "#{log_prefix_query} 'market_item_statuses' 不存在于 opts 中。"\n end\n \n Rails.logger.info "#{log_prefix_query} 返回原始话题关系。"\n original_topics_relation # 隐式返回\n end\n Rails.logger.info "[TecencMarket] 应用了简化的自定义过滤器 (V1.1_Test)。"\nend\n\n\n使用此简化过滤器的观察:\n\n* 没有我自定义过滤器参数的请求(例如,仅 /c/market/5/l/latest.json?filter=default):\n\n * 简化的过滤块日志正确:\n\n \n [TecencMarket_SimplifiedFilter_V1.1_Test] 通过 TopicQuery 接收的 Opts: {:category=>5, :filter=>"default", ...} \n [TecencMarket_SimplifiedFilter_V1.1_Test] 'market_item_statuses' 不存在于 opts。\n [TecencMarket_SimplifiedFilter_V1.1_Test] 返回原始话题关系。\n \n\n * 页面加载正常,返回 200 OK。\n\n* 带有我自定义过滤器参数的请求(例如 /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available):\n\n * 观察到 ListController 补丁日志:[TecencMarket_ListControllerExt_BuildOptsV3] 注入到 opts:market_item_statuses = Available\n”}{“content”: "* 在 … 毫秒内立即发生的 Completed 500 Internal Server Error

  • 至关重要的是,没有任何来自简化过滤器块内部的日志(没有 [TecencMarket_SimplifiedFilter_V1.1_Test]... 的行)出现在此失败请求的日志中。

这表明 500 错误发生在 TopicQuery 使用 opts 哈希(现在包含我自定义参数)初始化之后,但在或刚刚当 Discourse 核心的 TopicQuery#apply_custom_filters 机制试图执行我注册的(现在非常简单的)过滤器块时。

我在尝试从 development.log 中孤立导致请求失败的 Ruby 异常和完整的回溯信息方面遇到困难(我收集到的日志片段显示了 500 的行本身,但没有显示前面详细的错误信息)。

后续问题:

鉴于:

  1. 现已成功将自定义参数注入到 TopicQuery.options,这是通过 ListController 更新实现的。

  2. 当这些自定义参数存在于 opts 中时,发生了 500 错误。

  3. 这个 500 错误发生在甚至执行极其简化的自定义过滤器块(只记录日志并返回原始关系)之前。

  4. 这是在 Discourse 3.5.0.beta3-dev 版本上。

什么可能导致 TopicQuery 本身,或其 apply_custom_filters 方法,在调用注册的自定义过滤器块之前,因 options 哈希中包含这些插件特定的键而出错?我们之前怀疑的 LocalJumpError 仍然在处理过滤器块迭代或调用的底层有关联,即使我简化的块只是隐式返回?

关于在 TopicQuery 行为中检查这些类型的自定义选项的下一步建议,或关于如何更稳健地获取导致 500 错误的完整回溯信息的指导,将非常有帮助。" }