2015-04-07 13 views
5

मेरे पास रैक मिडलवेयर का एक टुकड़ा है जो सबडोमेन के माध्यम से किरायेदार लोड करता है, और कुछ डिफ़ॉल्ट सेटिंग्स लागू करता है। मिडलवेयर, सुंदर नहीं होने पर, क्या यह पर्याप्त काम ठीक है। हालांकि, जब ऐप के भीतर एक अपवाद फेंक दिया जाता है तो मिडलवेयर "स्ट्रिप्स" पूर्ण स्टैक ट्रेस होता है। जब मैं जाल कहता हूं तो मेरा मतलब है कि यह अपेक्षित स्टैक ट्रेस छुपाता है।रैक मिडलवेयर "फँसाने" स्टैक ट्रेस

यहां एक उदाहरण है।

मैं बहुत की तरह एक एक नियंत्रक कार्रवाई में एक अपवाद फेंक कर रहा हूँ:

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 

मैं गहरे लाल रंग का 2.2.0p0 और rails 4.1.8 चला रहा हूँ:

यहाँ मिडलवेयर है।

मैंने इसके लिए जाल खोजे हैं लेकिन कुछ भी नहीं मिला, शायद इसलिए कि मैं सही चीज़ के लिए सर्च नहीं कर रहा हूं।

यह क्यों हो रहा है और मैं क्या गलत कर रहा हूं पर कोई विचार?

चीयर्स!

उत्तर

7

मैं अंत में इस का हल मिल गया। यह पता चला है कि मेरा आवेदन माना जाता है कि आखिरी पंक्ति मिडलवेयर में है। मैं components निर्देशिका में स्थित स्थानीय रेल इंजन में शेष कोड चला रहा था। हमें बस इतना करना था कि BacktraceCleaner के लिए एक नया सिलेंसर बनाएं। नोटिस घटक डीआईआर अब शामिल है।

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

यदि आप यहां रुचि रखते हैं तो रेलवे प्रोजेक्ट पर पोस्ट किया गया है, इस बारे में मैंने विस्तार से इसे दोहराने के तरीके के बारे में बताया है। https://github.com/rails/rails/issues/22265

0

आप कुछ भी गलत नहीं कर रहे हैं। लेकिन सफाई के लिए बहुत सारे मिडलवेयर जाल अपवाद हैं, जिसमें मिडलवेयर शामिल है कि रैक विकास मोड में स्वचालित रूप से आवेषण करता है। वहाँ एक विशिष्ट रैक मिडलवेयर विकास कि ध्यान में न आया अपवादों को पकड़ने और एक उचित एचटीएमएल बजाय पृष्ठ एक कच्चे ढेर डंप दे देंगे में डाला है (जो आप अक्सर आम एप्लिकेशन सर्वर के साथ बिल्कुल भी नहीं देख सकेंगे।)

  • आप कर सकते हैं अपने शीर्ष स्तर के चारों ओर एक प्रारंभ/बचाव/अंत डालकर अपवाद को पकड़ें। अगर आप सबकुछ प्राप्त करना चाहते हैं, तो "अपवाद" को पकड़ने के लिए याद रखें, न केवल डिफ़ॉल्ट "बचाव"। और यदि आप इस कोड को छोड़ने जा रहे हैं तो आप अपवाद को फिर से फेंकना चाहेंगे।
  • आप उत्पादन मोड में भाग सकते हैं - जो कि रैक द्वारा स्वचालित रूप से डालने से मिडलवेयर को रोक सकता है।
  • आप यह पता लगा सकते हैं कि कौन सा मिडलवेयर डाला गया है (रेल में: "रेक मिडलवेयर") और फिर मैन्युअल रूप से मिडलवेयर को हटाएं (रेल में "config.middleware.delete" या "config.middleware.disable")।

शायद अन्य विधियां हैं।

3

आपका मिडलवेयर अच्छा लगता है। मुझे लगता है कि आपको अपनी backtrace_cleaner सेटिंग के साथ कोई समस्या है। शायद क्लीनर को तीसरे पक्ष के मणि द्वारा ओवरराइड किया जाता है। इससे पहले कि त्रुटि को ऊपर उठाने नियंत्रक कार्रवाई विधि में एक ब्रेकपाइंट (डिबगर) डाल प्रयास करें, और प्रिंट:

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

सभी साइलेंसर जो गैर एप्लिकेशन निशान बंद पट्टी के स्रोत स्थान देखने दें। डिफ़ॉल्ट रूप से इसे केवल रेल :: बैकट्रैक क्लेनर का उपयोग करना चाहिए जो रेलवे-4.1.8/lib/rails/backtrace_cleaner पर रेखांकित करता है।rb

सीधे साइलेंसर स्रोत कोड देखने के लिए:

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

अधिक से 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

संबंधित मुद्दे