2013-05-15 21 views
6

के अंदर एक विशिष्ट प्रकार की सभी त्रुटियों को बचाएं मेरे पास एक मॉड्यूल है जिसमें मैं एक परियोजना के लिए अपने सभी एन्क्रिप्शन/डिक्रिप्शन कार्यों को कर रहा हूं। मैं इस मॉड्यूल में होने वाले OpenSSL::Cipher::CipherError अपवादों को पकड़ना चाहता हूं ताकि मैं उन्हें संभाल सकूं।मॉड्यूल

यह एक मॉड्यूल के अंदर की तरह

rescue_from OpenSSL::Cipher::CipherError, :with => :cipher_error 

कुछ करने के लिए संभव है?

+1

क्या आप उस मॉड्यूल को नियंत्रक के अंदर शामिल कर रहे हैं या नहीं? 'rescue_from' का उपयोग केवल नियंत्रकों के अंदर किया जाना है, इसलिए इस तरह की कुछ सादे पुरानी रूबी वस्तुओं के अंदर कुछ गंदे हैक शामिल होंगे। – shime

+0

आह, समझा। धन्यवाद @shime – Matt

+0

मदद करने के लिए खुश। अगर आप जानना चाहते हैं कि गंदे हैक्स द्वारा मेरा क्या मतलब है, तो यहां देखें: http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/ - मुझे पसंद नहीं है रूबी में जब आप इसे करते हैं तो चीजें कैसे दिखती हैं और ऐसा लगता है कि अनावश्यक अव्यवस्था को जोड़ना। अपने तरीके से अपवाद हैंडलिंग निकालना आपके कोड के विश्वास को बेहतर बनाने का एक तरीका है, जो आपके परिदृश्य में सबसे अधिक फिट बैठता है। इसके बारे में यहां और पढ़ें: http://avdi.org/talks/confident-code-railsconf-2011/ – shime

उत्तर

7

मैंने थोड़ा जांच की है और समाधान के साथ आया है। आपने कहा कि आपके पास एक मॉड्यूल है जिसमें आप अपना एन्क्रिप्शन करते हैं। मुझे लगता है कि मॉड्यूल एक सिंगलटन का प्रतिनिधित्व करता है। मेरा समाधान, हालांकि, इसके बजाय आपके पास एक उदाहरण है।

class Crypto 
    def self.instance 
     @__instance__ ||= new 
    end 
end 

मॉड्यूल में एन्क्रिप्शन व्यवहार निकालें।

module Encryptable 
    def encrypt 
     # ... 
    end 

    def decrypt 
     # ... 
    end 
end 

अपवादों को संभालने वाला एक नया मॉड्यूल बनाएं।

module ExceptionHandler 
    extend ActiveSupport::Concern 

    included do 
    include ActiveSupport::Rescuable 
    rescue_from StandardError, :with => :known_error 
    end 

    def handle_known_exceptions 
    yield 
    rescue => ex 
    rescue_with_handler(ex) || raise 
    end 

    def known_error(ex) 
    Rails.logger.error "[ExceptionHandler] Exception #{ex.class}: #{ex.message}" 
    end 
end 

तो अब आप अपने Crypto अंदर नव handle_known_exceptions परिभाषित उपयोग कर सकते हैं। यह बहुत सुविधाजनक नहीं है क्योंकि आपने ज्यादा हासिल नहीं किया है। ,

class CryptoDelegator 
    include ExceptionHandler 

    def initialize(target) 
    @target = target 
    end 

    def method_missing(*args, &block) 
    handle_known_exceptions do 
     @target.send(*args, &block) 
    end 
    end 
end 

पूरी तरह से Crypto का आरंभीकरण ओवरराइड करने के लिए:

class Crypto 
    include ExceptionHandler 

    def print_bunnies 
    handle_known_exceptions do 
     File.open("bunnies") 
    end 
    end 
end 

यह करने के लिए अगर हम एक डैलिगेटर करता है परिभाषित कोई ज़रूरत नहीं है कि हम के लिए: आप अभी भी हर विधि के अंदर अपवाद संचालक कॉल करनी होगी इसके बजाय प्रतिनिधिमंडल का उपयोग करें।

class Crypto 
    include Encryptable 

    def self.new(*args, &block) 
    CryptoDelegator.new(super) 
    end 

    def self.instance 
     @__instance__ ||= new 
    end 
end 

और यही वह है!

+1

पवित्र धूम्रपान, यह बहुत बढ़िया है - बहुत बहुत धन्यवाद! मैं इसे एक दूंगा !! – Matt

+0

हाहा, यह मुझे परेशान कर रहा था क्योंकि मैंने अपने प्रश्न को दो बार पूछा है। इसके साथ खेलना मेरे लिए बहुत मजेदार था, इसलिए मैंने एक मणि बनाने का फैसला किया है जो रेल के बाहर 'rescue_from' को सक्षम बनाता है। https://github.com/shime/rescue_from_ruby – shime

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