रूबी और / या रेल में कस्टम त्रुटि प्रकारों को कहाँ परिभाषित करें?


149

क्या रूबी लाइब्रेरी (मणि) या रूबी ऑन रेल्स एप्लिकेशन में कस्टम त्रुटि प्रकारों को परिभाषित करने के लिए सबसे अच्छा अभ्यास है? विशेष रूप से:

  1. वे परियोजना में संरचनात्मक रूप से कहां हैं? एक अलग फ़ाइल, प्रासंगिक मॉड्यूल / वर्ग परिभाषा के साथ, कहीं और?
  2. वहाँ किसी भी सम्मेलनों जब स्थापित है कि कर रहे हैं करने के लिए और जब नहीं एक नया त्रुटि प्रकार बनाने के?

विभिन्न पुस्तकालयों में चीजों को करने के विभिन्न तरीके हैं, और मैंने किसी भी वास्तविक पैटर्न पर ध्यान नहीं दिया है। कुछ पुस्तकालय हमेशा कस्टम त्रुटि प्रकारों का उपयोग करते हैं जबकि अन्य उनका उपयोग नहीं करते हैं; कुछ में सभी त्रुटियां हैं, जबकि StandardError का विस्तार अन्य लोगों ने पदानुक्रम में किया है; कुछ सिर्फ खाली वर्ग की परिभाषाएँ हैं, दूसरों में हर तरह की चतुराई है।

ओह, और सिर्फ इसलिए कि मुझे ऐसा लगता है कि इन "त्रुटि प्रकारों" को कॉल करना अस्पष्ट है, मेरे कहने का मतलब यह है:

class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end

जवाबों:


219

रत्न के लिए

मैंने कई बार देखा है कि आप अपवादों को इस तरह से परिभाषित करते हैं:

gem_dir / lib / gem_name / exceptions.rb

और इस रूप में परिभाषित किया गया है:

module GemName

  class AuthenticationError < StandardError; end
  class InvalidUsername < AuthenticationError; end

end

इसका एक उदाहरण कुछ इस तरह से होगा जैसे कि चित्रपट में

रूबी ऑन रेल्स

अपवाद के रूप में एक फ़ाइल के तहत उन्हें अपने परिवाद / फ़ोल्डर में रखें। शब्द, जो कुछ इस तरह दिखाई देगा:

module Exceptions
  class AuthenticationError < StandardError; end
  class InvalidUsername < AuthenticationError; end
end

और आप इसे इस तरह उपयोग करेंगे:

raise Exceptions::InvalidUsername

रत्नों के लिए, ऐसा लगता है कि आपको अपवाद फ़ाइल भी शामिल करनी पड़ सकती है। इस उदाहरण को फिर से देखें httparty: github.com/jnunemaker/httparty/blob/…
जेसन स्विट

37
Exceptionsमॉड्यूल में उन्हें नाम स्थान क्यों दिया गया ?
एबीमगिल

13
मुझे लगता है कि /libत्रुटियों के लिए जगह नहीं हो सकती है। वे बहुत ही विशिष्ट अनुप्रयोग हैं और मैं इस धारणा के तहत हूं कि जो कोड मैं डाल रहा हूं /libउसका मतलब कोड है जो अन्य अनुप्रयोगों में पुन: उपयोग किया जा सकता है।
वूलिवोंग

1
रेल के निर्देशों पर रूबी ने मेरे लिए काम नहीं किया - क्या वास्तव में इस नई फ़ाइल को विशिष्ट मामले में लोड करने के लिए कुछ अतिरिक्त कदम की आवश्यकता है?
मियोकी

1
@ABMagil लगता है कि मुझे अन्यथा Unable to autoload constant Exceptions, expected /app/lib/exceptions.rb to define itविकल्प के प्रति एक वर्ग होगा जो मुझे लगता है कि एक वर्ग होगा
ryan2johnson9

25

मुझे लगता है कि आपके प्रोजेक्ट में कोएक्टिव सोर्स फाइल्स होने के लिए, आपको उस क्लास में त्रुटियों को परिभाषित करना चाहिए जिसमें उन्हें फेंक सकते हैं और कहीं नहीं।

कुछ पदानुक्रम सहायक हो सकते हैं - नामस्थान अनावश्यक नामों को प्रकार के नामों से बाहर रखने में अच्छे हैं - लेकिन यह स्वाद का मामला है - ओवरबोर्ड जाने की कोई आवश्यकता नहीं है बशर्ते आपके ऐप में कम से कम एक कस्टम अपवाद प्रकार हो जिसे आप अंतर करने के लिए उपयोग करते हैं 'जानबूझकर' और 'आकस्मिक' अपवाद मामलों के बीच।


8
सिद्धांत रूप में आप सही हैं, तब क्या होता है जब एक ही त्रुटि को विभिन्न वर्गों द्वारा पूरी तरह से अलग-अलग स्थितियों में उठाया जा सकता है?
Alain

1
@ किसी भी अपवाद / त्रुटि मॉड्यूल में एक से अधिक वर्ग द्वारा उपयोग की गई त्रुटियों को परिभाषित क्यों नहीं करते, लेकिन एकल वर्ग में परिभाषित अन्य सभी को छोड़ दें जो उनका उपयोग करता है?
स्कॉट डब्ल्यू

@ScottW, उस स्थिति में, हम डेवलपर को जांच करने के लिए याद रखना चाहते हैं।
जोश सेंट जेक

22

रेल में आप app/errorsनिर्देशिका बना सकते हैं

# app/errors/foo_error.rb
class FooError < StandardError; end

स्प्रिंग / सर्वर को पुनरारंभ करें और इसे चुनना चाहिए


मुझे इन अपवादों को कैसे उठाना चाहिए?
निखिल वाघ

@NikhilWagh या तो raise FooError, "Example message..."याraise FooError.new("Example message...")
schpet

13

यह एक पुराना प्रश्न है, लेकिन मैं यह साझा करना चाहता था कि मैं रेल में कस्टम त्रुटियों को कैसे संभाल रहा हूं, जिसमें त्रुटि संदेश, परीक्षण और ActiveRecordमॉडल के साथ इसे संभालना शामिल है ।

कस्टम त्रुटि बनाना

class MyClass
  # create a custome error
  class MissingRequirement < StandardError; end

  def my_instance_method
    raise MyClass::MissingRequirement, "My error msg" unless true   
  end
end

परीक्षण (न्यूनतम)

test "should raise MissingRequirement if ____ is missing"
  # should raise an error
  error = assert_raises(MyClass::MissingRequirement) {
    MyClass.new.my_instance_method
  }

  assert error.message = "My error msg"
end

ActiveRecord के साथ

मुझे लगता है कि यह ध्यान देने योग्य है कि यदि किसी ActiveRecordमॉडल के साथ काम करना है , तो एक लोकप्रिय पैटर्न मॉडल में नीचे बताए अनुसार एक त्रुटि जोड़ना है, ताकि आपकी मान्यता विफल हो जाए:

def MyModel < ActiveRecord::Base
  validate :code_does_not_contain_hyphens

  def code_does_not_contain_hyphens
    errors.add(:code, "cannot contain hyphens") if code.include?("-")
  end
end

जब सत्यापन चलाया जाता है, तो यह विधि ActiveRecord के ActiveRecord::RecordInvalidत्रुटि वर्ग पर वापस आ जाएगी और सत्यापन विफल होने का कारण बनेगी।

उम्मीद है की यह मदद करेगा!


9

यह सुनिश्चित करने के लिए कि एकाधिक कस्टम त्रुटि वर्गों के लिए ऑटोलैडिंग कार्य के रूप में रेल 4.1.10 में अपेक्षित है, आप प्रत्येक के लिए अलग-अलग फाइलें निर्दिष्ट करना चाहेंगे। यह अपने गतिशील रूप से पुनः लोड के साथ विकास में काम करना चाहिए।

हाल ही के प्रोजेक्ट में त्रुटियों को दूर करने के तरीके में यह है:

में lib/app_name/error/base.rb

module AppName
    module Error
        class Base < StandardError; end
    end
end

और बाद की कस्टम त्रुटियों में, जैसे lib/app_name/error/bad_stuff.rb

module AppName
    module Error
        class BadStuff < ::AppName::Error::Base; end
    end
end

आपको तब अपनी त्रुटियों को कॉल करने में सक्षम होना चाहिए:

 raise AppName::Error::BadStuff.new("Bad stuff just happened")

और यदि आप प्रत्येक नई त्रुटि के लिए एक अलग फ़ाइल नहीं चाहते हैं, तो बस उन सभी को lib/app_name/error.rb
डालें

एक हो रही है uninitialized constant MyController::AppName। मैं अपने कंट्रोलर में उठा रहा हूं
निखिल वाघ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.