2015-04-07 17 views
5

Tôi có một phần Phần mềm trung gian giá để tải người thuê, qua tên miền phụ và áp dụng một số cài đặt mặc định. Phần mềm trung gian, trong khi không đẹp, công việc của nó có đủ tốt không. Tuy nhiên, khi một ngoại lệ được ném vào trong ứng dụng, phần mềm trung gian "bẫy" toàn bộ dấu vết ngăn xếp. Khi tôi nói bẫy tôi có nghĩa là nó ẩn dấu vết ngăn xếp dự kiến.Giá đỡ trung gian "bẫy" ngăn xếp dấu vết

Đây là một ví dụ.

Tôi ném một ngoại lệ trong một hành động một bộ điều khiển như vậy:

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

Bạn mong chờ rằng stack trace sẽ tham khảo vị trí này nhưng nó không. Thay vào đó nó tham chiếu một dòng trong phần mềm trung gian.

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' 

Tại sao điều này xảy ra? Bạn đã từng thấy điều gì như thế này chưa?

Đây là middleware:

# 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 

Tôi đang chạy ruby ​​2.2.0p0rails 4.1.8.

Tôi đã tìm kiếm trên web về điều này nhưng không thể tìm thấy bất kỳ điều gì, có thể vì tôi không cố gắng làm đúng.

Bất kỳ suy nghĩ nào về lý do điều này xảy ra và những gì tôi đang làm sai?

Chúc mừng!

Trả lời

7

cuối cùng tôi đã tìm thấy các giải pháp này. Nó chỉ ra rằng dòng cuối cùng trong những gì được coi là ứng dụng của tôi là trong middleware. Tôi đã chạy phần còn lại của mã trong một động cơ đường ray địa phương nằm trong một thư mục components. Tất cả những gì chúng tôi cần làm là tạo bộ phận giảm thanh mới cho BacktraceCleaner. Thông báo các thành phần dir bây giờ được bao gồm.

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

Nếu bạn quan tâm đến đây là vấn đề tôi đăng trên dự án đường ray về cách sao chép chi tiết điều này. https://github.com/rails/rails/issues/22265

0

Bạn không làm gì sai. Nhưng có rất nhiều ngoại lệ bẫy trung gian để làm sạch, bao gồm phần mềm trung gian mà Rack chèn tự động trong chế độ phát triển. Có một middleware Rack cụ thể được chèn vào trong quá trình phát triển sẽ bắt các ngoại lệ chưa được khai báo và đưa ra một trang HTML hợp lý thay vì một đống stack thô (mà bạn thường sẽ không thấy ở tất cả các máy chủ ứng dụng phổ biến.)

  • Bạn có thể bắt ngoại lệ cho mình bằng cách đặt một bắt đầu/cứu/kết thúc xung quanh cấp cao nhất của bạn. Hãy nhớ để bắt "ngoại lệ", không chỉ là "cứu hộ" mặc định với không có arg, nếu bạn muốn nhận được tất cả mọi thứ. Và bạn có thể muốn ném lại ngoại lệ nếu bạn sẽ để lại mã này.
  • Bạn có thể chạy ở chế độ sản xuất - có thể tự động chèn phần mềm trung gian vào Rack.
  • Bạn có thể tìm thấy phần mềm trung gian nào được chèn (trong Rails: "rake middleware") và sau đó loại bỏ phần mềm trung gian theo cách thủ công (trong Rails "config.middleware.delete" hoặc "config.middleware.disable").

Có thể có các phương pháp khác.

3

Phần mềm trung gian của bạn có vẻ tốt. Tôi nghĩ bạn có vấn đề với cài đặt backtrace_cleaner của mình. Có lẽ chất tẩy rửa bị ghi đè bởi viên ngọc của bên thứ 3. Hãy thử đặt một breakpoint (debugger) trong phương pháp hành động điều khiển trước khi nâng lỗi, và in:

puts env['action_dispatch.backtrace_cleaner'].instance_variable_get(:@silencers).map(&:source_location).map{|l| l.join(':')} 

để xem vị trí nguồn của tất cả các bộ phận giảm thanh mà lột dấu vết phi ứng dụng. Theo mặc định, nó chỉ nên sử dụng Rails :: BacktraceCleaner nằm ở railties-4.1.8/lib/rails/backtrace_cleaner.rb

Trực tiếp xem mã nguồn silencer:

puts env['action_dispatch.backtrace_cleaner'].instance_variable_get(:@silencers).map{|s| RubyVM::InstructionSequence.disasm s } 

Xem thêm từ https://github.com/rails/rails/blob/master/railties/lib/rails/backtrace_cleaner.rb https://github.com/rails/rails/blob/master/activesupport/lib/active_support/backtrace_cleaner.rb

Các vấn đề liên quan