.NET: कौन सा अपवाद फेंकता है जब एक आवश्यक कॉन्फ़िगरेशन सेटिंग गुम हो जाती है?


123

यहाँ एक मानक परिदृश्य है:

if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
   throw new SomeStandardException("Application not configured correctly, bozo.");

समस्या यह है, मैं पूरी तरह से निश्चित नहीं हूं कि कौन सा अपवाद SomeStandardExceptionहोना चाहिए।

मैंने 3.5 फ्रेमवर्क का उपयोग किया और दो संभावित उम्मीदवारों को पाया: ConfigurationExceptionऔर ConfigurationErrorsException

System.Configuration.ConfigurationException

कॉन्फ़िगरेशन सिस्टम त्रुटि होने पर अपवाद को फेंक दिया जाता है।

टिप्पणियों

ConfigurationExceptionयदि एप्लिकेशन कॉन्फ़िगरेशन फ़ाइल में डेटा को पढ़ने या लिखने का प्रयास करता है, लेकिन अपवाद असफल है, लेकिन असफल है। इसके कुछ संभावित कारणों में कॉन्फ़िगरेशन फ़ाइल में विकृत एक्सएमएल, फ़ाइल अनुमति मुद्दे और कॉन्फ़िगरेशन गुण शामिल हो सकते हैं जो मान्य नहीं हैं।

ध्यान दें:

ConfigurationExceptionवस्तु पिछली संगतता के लिए बनाए रखा है। ConfigurationErrorsException वस्तु विन्यास प्रणाली के लिए यह बदल देता है।

यह अपवाद वास्तव में मुझे क्या चाहिए, के लिए एकदम सही लगता है, लेकिन यह अप्रचलित चिह्नित किया गया है, इसलिए, अथाए पर ixnay।

यह हमें अच्छी तरह से हैरान कर देता है ConfigurationErrorsException:

System.Configuration.ConfigurationErrorsException

वर्तमान मान EnableSessionState मानों में से एक नहीं है।

जैसा कि आप देख सकते हैं, इसका प्रलेखन पूरी तरह से बेकार है। (यह स्थानीय और ऑनलाइन मदद दोनों में इस तरह से है।) कक्षा की एक परीक्षा से ही पता चलता है कि मैं जो चाहता हूं, उसके लिए यह भारी है।

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

क्या समाधान, यदि कोई हो, क्या आप लोग इसके लिए उपयोग कर रहे हैं, और क्या मैं इसे चूसना और इसके लिए अपना स्वयं का अपवाद रोल करने जा रहा हूं?

एडेंडा को संपादित करें

कुछ ने पूछा है कि मैं डिफ़ॉल्ट मान प्रदान कर सकता हूं या नहीं, और जारी रख सकता हूं। कुछ मामलों में, हाँ, और उन मामलों में, अपवाद नहीं फेंका जाएगा। हालाँकि, कुछ सेटिंग्स के लिए, यह लागू नहीं होगा। उदाहरण के लिए: डेटाबेस सर्वर नाम और क्रेडेंशियल्स, प्रमाणीकरण सर्वर, और स्थापित थर्ड पार्टी एप्लिकेशन को पथ।

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


1
के लिए प्रलेखन System.Configuration.ConfigurationErrorsException अद्यतन किया गया है।
स्लॉलाइफ

जवाबों:


36

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

यह आपका आवेदन है- जब तक आप इसे दस्तावेज करते हैं और स्पष्ट रूप से उस अपवाद को इंगित करते हैं जो एक लापता कॉन्फ़िगरेशन मान के विशिष्ट मामले में फेंक दिया जाएगा, आप अपनी पसंद के किसी भी अपवाद का उपयोग कर सकते हैं। यदि आप एक लापता मूल्य का बहुत विशिष्ट संकेत चाहते हैं , तो आप अपना स्वयं का कॉन्फ़िगरेशन लिखने पर विचार कर सकते हैं।

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

EDIT: इस मामले में अपना खुद का अपवाद लिखना इस बात की गारंटी देता है कि इस बात का कोई भ्रम नहीं होगा कि अपवाद कहां से आ रहा है- फ्रेमवर्क, या आपका एप्लिकेशन। ढांचा आपके कस्टम अपवादों को कभी नहीं फेंकेगा।

अद्यतन: मैं टिप्पणियों से सहमत हूं, इसलिए मैंने उप-विन्यास को कॉन्फ़िगरेशन से अपवाद में बदल दिया है। मुझे लगता है कि यह आम तौर पर मौजूदा फ्रेमवर्क अपवादों से कस्टम अपवादों को उप-वर्ग करने के लिए एक अच्छा विचार है, जहां संभव हो, अपवाद वर्ग से परहेज करें जब तक कि आपको एप्लिकेशन-विशिष्ट अपवाद की आवश्यकता न हो।


17
मैं कुछ हद तक असहमत हूं। यदि आप किसी मौजूदा अपवाद का उपयोग करने जा रहे हैं, तो इसका उपयोग बिल्कुल किया जाना चाहिए क्योंकि प्रलेखन कहता है कि इसका उपयोग किया गया है, अन्यथा आप उन लोगों को भ्रमित करेंगे जो आपके साथ आते हैं। यदि आप कुछ अलग करने जा रहे हैं, तो अपना खुद का अपवाद बनाएं, जैसे आपने कहा था।
रॉबर्ट सी। बार्थ

1
मैं असहमत हूं। जब तक आपके पास अपने कस्टम अपवाद को पकड़ने के लिए परिदृश्य नहीं होता है, तब तक कॉन्फ़िगरेशन त्रुटि के मामले में संभावना नहीं है, मौजूदा प्रकार (कॉन्फ़िगरेशनErrorsException) का पुन: उपयोग करना बेहतर है। और यदि आप एक कस्टम प्रकार बनाते हैं, तो मैं इसे संबंधित प्रकार से कॉन्फ़िगर करूँगा जैसे कि कॉन्फ़िगरेशनईरॉर्सएक्स अपवाद।
जो

@ रॉबर्ट और जो- मैं यह सुझाव नहीं दे रहा हूं कि मौजूदा फ्रेमवर्क अपवादों को उनके इच्छित कार्य के साथ असंगत रूप से उपयोग किया जाना चाहिए, बस यह है कि कुछ लचीलापन है जब तक कि विशिष्ट मामले (लापता मूल्य) सामान्य मामले (कॉन्फ़िगरेशनErrorsException) के साथ फिट बैठता है।
डेव स्वार्स्की

1
यदि आप ASP.NET अनुप्रयोग के अपवाद को फेंक रहे हैं, तो इसके साथ समस्याएँ हो सकती हैं, जैसे कि कॉन्फ़िगरेशनErrorsException और उससे ली गई कक्षाएं संरक्षित OnError विधि या Global ASAX त्रुटि ईवेंट द्वारा नहीं पकड़ी गई हैं। इस प्रश्न को देखें मैंने पोस्ट किया है .... stackoverflow.com/questions/25299325/…
मिक

48

व्यक्तिगत रूप से, मैं InvalidOperationException का उपयोग करूंगा , क्योंकि यह ऑब्जेक्ट स्टेट के साथ एक समस्या है - कॉन्फ़िगरेशन सिस्टम नहीं। आखिरकार, क्या आपको इन सेटिंग्स को कोड द्वारा सेट नहीं करने देना चाहिए और साथ ही कॉन्फ़िगर नहीं करना चाहिए? यहाँ महत्वपूर्ण हिस्सा यह नहीं है कि app.config में कोई लाइन नहीं थी, लेकिन जानकारी का एक आवश्यक टुकड़ा मौजूद नहीं था।

मेरे लिए, कॉन्फ़िगरेशन एक्ससेप्शन (और यह प्रतिस्थापन है, कॉन्फ़िगरेशनErrorsException - भ्रामक MSDN डॉक्स के बावजूद) कॉन्फ़िगरेशन की बचत, पढ़ने, आदि में त्रुटियों के लिए है।


मैंने InvalidOperationException के लिए विकल्प चुना है, क्योंकि यह ASP.NET पेज द्वारा संरक्षित ऑनएयर विधि द्वारा संभाला गया है, जबकि कॉन्फ़िगरेशनErrorsException और उससे प्राप्त सभी अपवाद नहीं हैं
मिक

2
यह वास्तव में मुझे आश्चर्यचकित करेगा, अगर मुझे एक चालान अमान्य हो जाता है यदि मुझे कॉन्फ़िगरेशन गलत मिलता है।
केयूएलजे

18

जैसा कि डैनियल रिचर्डसन ने कहा, configurationErrorsException एक का उपयोग करने के लिए है। सामान्य तौर पर यह केवल अपने स्वयं के कस्टम अपवाद बनाने के लिए अनुशंसित है यदि आपके पास उन्हें संभालने के लिए एक परिदृश्य है। कॉन्फ़िगरेशन त्रुटियों के मामले में, जो आमतौर पर घातक होते हैं, यह शायद ही कभी होता है, इसलिए आमतौर पर मौजूदा कॉन्फ़िगरेशनErrorsException प्रकार का पुन: उपयोग करना अधिक उपयुक्त होता है।

.NET 2.0 से पहले, अनुशंसा System.Configuration.ConfigurationException का उपयोग करने के लिए थी । कॉन्फ़िगरेशन 2.0 अपवाद .NET 2.0 में अप्रचलित हो गया, उन कारणों के लिए जो मेरे लिए कभी भी स्पष्ट नहीं थे, और कॉन्फ़िगरेशन कॉन्फ़िगरेशन के उपयोग के लिए सिफारिश बदल गई।

मैं अपवाद को फेंकने के लिए एक सहायक विधि का उपयोग करता हूं, ताकि .NET 1.x से 2.0 में माइग्रेट होने पर अपवाद को एक स्थान पर बदलना आसान हो, या यदि Microsoft फिर से सिफारिश बदलने का निर्णय लेता है:

if(string.IsNullOrEmpty(Configuration.AppSettings("foobar")))
{
   throw CreateMissingSettingException("foobar");
}

...

private static Exception CreateMissingSettingException(string name)
{
    return new ConfigurationErrorsException(
        String.Format
        (
        CultureInfo.CurrentCulture,
        Properties.Resources.MissingConfigSetting,
        name
        )
        );
}

16

किस बारे में System.Configuration.SettingsPropertyNotFoundException?


IMO यह असली जवाब है। +1
LC

वास्तव में नहीं, क्योंकि: SettingsProperty ऑब्जेक्ट के लिए एक अपवाद प्रदान करता है जो नहीं मिला है। जो से आता है: आंतरिक रूप से उस वर्ग के रूप में उपयोग किया जाता है जो व्यक्तिगत विन्यास संपत्ति के बारे में मेटाडेटा का प्रतिनिधित्व करता है। जो कॉन्फ़िगरेशन के एक लापता मूल्य के समान नहीं है।
करोल हलीस्की

7

ConfigurationErrorsExceptionआपके द्वारा वर्णित स्थिति में फेंकने का सही अपवाद है। ConfigurationErrorsExceptionअधिक जानकारी के लिए MSDN प्रलेखन का एक पुराना संस्करण ।

http://msdn.microsoft.com/en-us/library/system.configuration.configurationerrorsexception(VS.80).aspx

पहले के MSDN सारांश और टिप्पणियां हैं:

  • कॉन्फ़िगरेशन-सिस्टम त्रुटि होने पर अपवाद को फेंक दिया जाता है।
  • ConfigurationErrorsException अपवाद है जब किसी भी त्रुटि तब होती है, जबकि विन्यास जानकारी को पढ़ने या लिखा जा रहा है फेंक दिया है।

7
प्रलेखन से: "यह एपीआई उत्पाद के बुनियादी ढांचे का समर्थन करता है और इसका उपयोग सीधे आपके कोड से करने का इरादा नहीं है। कॉन्फ़िगरेशन के एक नए उदाहरण को प्रारंभ करता है। कॉन्फ़िगरेशन क्लास।"
ओलेग श

6

कॉन्फ़िगरेशनप्लिमेंटेशन क्लास (जो कई कॉन्फ़िगरेशन से संबंधित वर्गों का आधार वर्ग है, जैसे कॉन्फ़िगरेशनसेन) में OnRequiredPropertyNotFound नामक एक विधि है (अन्य सहायक विधियाँ भी हैं)। आप शायद उन लोगों को बुला सकते हैं।

OnRequiredPropertyNotFound को इस तरह लागू किया गया है:

protected virtual object OnRequiredPropertyNotFound(string name) {
    throw new ConfigurationErrorsException(SR.GetString("Config_base_required_attribute_missing", new object[] { name }), this.PropertyFileName(name), this.PropertyLineNumber(name)); }

1

मैं इसे चूसूंगा और अपना रोल करूंगा ... लेकिन इससे पहले कि आप ऐसा करें, क्या यह संभव है कि सिस्टम इस कॉन्फ़िगरेशन सेटिंग के लिए डिफ़ॉल्ट मान ले? मैं आम तौर पर ऐसा करने का प्रयास करता हूं कि हर सेटिंग के लिए मि बू ऑप्स प्रबंधन लोक मिल सकता है ... (या शायद मुझे कहना चाहिए, जितनी संभव हो उतनी सेटिंग्स के लिए - कुछ के लिए सिस्टम को डिफ़ॉल्ट रूप से निर्णय लेना स्पष्ट रूप से उचित नहीं है। ..)

सामान्य तौर पर एक कस्टम अपवाद बहुत प्रयास नहीं है ... यहाँ एक उदाहरण है ...

[Serializable]
public class MyCustomApplicationException : ApplicationException
{
    #region privates
    #endregion privates

    #region properties
    #endregion properties

    public MyCustomApplicationException (string sMessage,
        Exception innerException)
        : base(sMessage, innerException) { }
    public MyCustomApplicationException (string sMessage)
        : base(sMessage) { }
    public MyCustomApplicationException () { }

    #region Serializeable Code
    public MyCustomApplicationException (
       SerializationInfo info, StreamingContext context)
        : base(info, context) { }
    #endregion Serializeable Code
}

2
MSDN: ... एक ऐसा अनुप्रयोग जिसे स्वयं अपवाद बनाने की आवश्यकता है, [...] अपवाद अपवाद अपवाद वर्ग से प्राप्त करें। यह मूल रूप से सोचा गया था कि कस्टम अपवाद ApplicationException वर्ग से प्राप्त होना चाहिए; हालांकि व्यवहार में इसे महत्वपूर्ण मूल्य नहीं मिला है।
गैसपार नागी

हां, मुझे लगता है कि ऐसा इसलिए हुआ क्योंकि MS प्रोग्रामर जिन्होंने फ्रेमवर्क को कोड किया था, उन्होंने ApplicationException से कई CLR अपवाद निकाले, इस प्रकार भेद के महत्व को नष्ट कर दिया .. मैं अभी भी इसे करता हूं, क्योंकि मुझे इसमें कोई नुकसान नहीं दिखता ...
चार्ल्स बयाना

1

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


0

मेरा सामान्य नियम होगा:

  1. यदि अनुपलब्ध कॉन्फ़िगरेशन का मामला बहुत सामान्य नहीं है और मेरा मानना ​​है कि मैं इस मामले को अन्य अपवादों की तुलना में अलग ढंग से संभालना नहीं चाहूंगा, तो मैं एक उपयुक्त संदेश के साथ मूल "अपवाद" वर्ग का उपयोग करता हूं:

    नया अपवाद फेंकें ("मेरा संदेश यहाँ")

  2. अगर मैं चाहता हूं, या लगता है कि एक उच्च संभावना है, तो मैं इस मामले को अन्य अपवादों की तुलना में एक अलग तरीके से संभालना चाहता हूं, मैं अपने स्वयं के प्रकार को रोल करूंगा क्योंकि लोग पहले से ही यहां सुझाव दे चुके हैं।


0

मैं आपके प्रश्न के आधार से असहमत हूं:

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

System.Exception ( Exception Class) पर MSDN प्रलेखन के अनुसार , प्रदर्शन कारणों (जिसे स्टैक ओवरफ़्लो और अन्य जगहों पर अन्य लोगों द्वारा इंगित किया गया है) के लिए आपको वास्तव में उपयोगकर्ता इनपुट त्रुटियों के अपवादों को नहीं फेंकना चाहिए। अच्छी तरह से - यदि उपयोगकर्ता इनपुट गलत तरीके से दर्ज किया गया है, तो आपका फ़ंक्शन झूठा नहीं हो सकता है, और फिर इनायत से बाहर निकलें। यह एक डिजाइन समस्या का अधिक प्रतीत होता है, फिर एक मुद्दा जिसके साथ अपवाद को फेंकना है।

जैसा कि दूसरों ने बताया है, अगर आपको वास्तव में अपवाद को फेंकना है - जो भी कारण से - ऐसा कोई कारण नहीं है कि आप System.Exception से विरासत में अपने अपवाद प्रकार को परिभाषित नहीं कर सके।


2
वास्तव में इस विशिष्ट परिदृश्य में प्रदर्शन क्यों होगा? IUC, तब अपवाद को एक बार बिल्कुल फेंक दिया जाता है और प्रक्रिया की संभावना वैसे भी नीचे जाती है (बेशक, उपयोगकर्ता को एक अच्छा पॉप-अप दिखाने के बाद)। (जारी रखा जाए ...)

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

1
आपने कुछ याद किया: "जब एक एप्लिकेशन कॉन्फ़िगरेशन सेटिंग गायब है या इसमें एक अमान्य मान है", तो यह खराब उपयोगकर्ता इनपुट के समान नहीं है। यह एक मूल कॉन्फ़िगरेशन है जो गायब है। एक कस्टम अपवाद होना चाहिए और ऐप को चलने से रोकना चाहिए।
जुल्म

2
इस विशेष अनुप्रयोग में, यह लगभग पूरी तरह से विन्यास फाइल में सेटिंग्स द्वारा संचालित है। यदि सेटिंग्स इसमें नहीं हैं (जहां वे एन्क्रिप्ट किए गए हैं), तो एप्लिकेशन जारी नहीं रह सकता है और समाप्त होना चाहिए। एक अपवाद वस्तुतः आवश्यक है।
माइक हॉफर

1
यह निश्चित रूप से शब्दार्थ में मिल सकता है, और आपके कोड की संरचना स्पष्ट रूप से आपकी स्थिति के लिए सबसे अच्छा कार्यान्वयन तय करेगी। फिर भी, यदि आपके पास डिजाइन में मुफ्त शासन था, तो मैं अभी भी एक वस्तु के साथ जाऊंगा त्रुटि और एक अपवाद पर एक सुंदर बाहर निकलने के लिए, प्रदर्शन एक मुद्दा है या नहीं।
मैट जॉर्डन

-2

आप XML एक्सेप्शन को इनहेरिट करने का प्रयास कर सकते हैं, या बस इसका उपयोग कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.