ruby-on-rails - Rack 中间件 "trapping"堆栈跟踪

标签 ruby-on-rails rack spree middleware

我有一个 Rack 中间件,它通过子域加载一个租户,并应用一些默认设置。中间件虽然不漂亮,但它的工作是否足够好。但是,当应用程序中抛出异常时,中间件会“捕获”完整的堆栈跟踪。当我说陷阱时,我的意思是它隐藏了预期的堆栈跟踪。

这是一个例子。

我在 Controller Action 中抛出异常,如下所示:

def index
  throw "Exception in a Rails controller action"
  @taxonomies = Spree::Taxonomy.all
end

您会期望堆栈跟踪会引用此位置,但事实并非如此。相反,它引用了中间件中的一行。
Completed 500 Internal Server Error in 139ms

UncaughtThrowError (uncaught throw "Exception in a Rails controller action"):
lib/tenant_manager/middleware/loader.rb:42:in `call'

为什么会发生这种情况?你以前见过这样的吗?

这是中间件:
# lib/tenant_manager/middleware/loader.rb
module TenantManager
  module Middleware
    class Loader
    # Middleware to detect an tenant via subdomain early in
    # the request process
    #
    # Usage:
    #   # config/application.rb
    #   config.middleware.use TenantManager::Middleware::Loader
    #
    # A scaled down version of https://github.com/radar/houser

      def initialize(app)
        @app = app
      end

      def call(env)
        domain_parts = env['HTTP_HOST'].split('.')
        if domain_parts.length > 2
          subdomain = domain_parts.first
          tenant = Leafer::Tenant.find_by_database(subdomain)
          if tenant
            ENV['CURRENT_TENANT_ID'] = tenant.id.to_s
            ENV['RAILS_CACHE_ID'] = tenant.database
            Spree::Image.change_paths tenant.database
            Apartment::Tenant.process(tenant.database) do
              country = Spree::Country.find_by_name('United States')
              Spree.config do |config|
                config.default_country_id = country.id if country.present?
                config.track_inventory_levels = false
              end
              Spree::Auth::Config.set(:registration_step => false)
            end
          end
        else
          ENV['CURRENT_TENANT_ID'] = nil
          ENV['RAILS_CACHE_ID'] = ""
        end
        @app.call(env)
      end

    end
  end
end

我正在运行 ruby​​ 2.2.0p0rails 4.1.8 .

我在网上搜索过这个,但找不到任何东西,可能是因为我没有寻找正确的东西。

关于为什么会发生这种情况以及我做错了什么的任何想法?

干杯!

最佳答案

我终于找到了解决这个问题的方法。事实证明,被认为是我的应用程序的最后一行是在中间件中。我在位于 components 的本地 Rails 引擎中运行其余代码目录。我们需要做的就是为 BacktraceCleaner 创建一个新的消音器.注意组件目录现在包括在内。

# config/initializers/backtrace_silencers.rb
Rails.backtrace_cleaner.remove_silencers!
Rails.backtrace_cleaner.add_silencer { |line| line !~ /^\/(app|config|lib|test|components)/}

如果您对此感兴趣,这是我在 rails 项目上发布的有关如何详细复制此内容的问题。 https://github.com/rails/rails/issues/22265

关于ruby-on-rails - Rack 中间件 "trapping"堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29498145/

相关文章:

ruby-on-rails - Spree Commerce - 按 sku 搜索订单

ruby-on-rails - 在 Spree Controller Decorator 上测试重写操作

ruby-on-rails - 保存搜索词 rails thinkingsphinx

ruby-on-rails - 有没有办法在 kaminari 中使用数组扩展?

ruby-on-rails - Rails 如何请求除 url 参数之外的 url?

ruby-on-rails - Rails 3 中的 require rack/openid 问题[ native 需要正常工作]

sinatra - main :Object (NoMethodError) Sinatra 的未定义方法 `run'

ruby-on-rails - rails 3.2 : Routing helpers in views break locally after other error

ruby 1.9、rvm、sinatra 和 rackup

ruby-on-rails - 如何在开发中使用 Spree 发送电子邮件