क्या फेंकने के बजाय अपवाद वस्तुओं को वापस करने के वैध कारण हैं?


45

यह प्रश्न किसी ओओ प्रोग्रामिंग भाषा पर लागू करने का इरादा है जो अपवाद से निपटने का समर्थन करता है; मैं केवल उदाहरण के लिए C # का उपयोग कर रहा हूं।

अपवाद आमतौर पर उठाए जाने का इरादा होता है जब एक समस्या उत्पन्न होती है कि कोड तुरंत संभाल नहीं सकता है, और फिर catchएक अलग स्थान (आमतौर पर एक बाहरी स्टैक फ्रेम) में एक खंड में पकड़ा जा सकता है ।

प्रश्न: क्या ऐसी कोई वैध परिस्थितियाँ हैं जहाँ अपवादों को फेंका और पकड़ा नहीं जाता है, लेकिन बस एक विधि से लौटा दिया जाता है और फिर त्रुटि वस्तुओं के रूप में चारों ओर से गुजरता है?

यह प्रश्न मेरे लिए आया क्योंकि .NET 4 की System.IObserver<T>.OnErrorविधि केवल यह बताती है कि: अपवादों को त्रुटि ऑब्जेक्ट के रूप में पास किया जा रहा है।

आइए एक और परिदृश्य देखें, सत्यापन। मान लें कि मैं पारंपरिक ज्ञान का पालन कर रहा हूं, और इसलिए मैं एक त्रुटि ऑब्जेक्ट प्रकार IValidationErrorऔर एक अलग अपवाद प्रकार के बीच अंतर कर रहा हूं ValidationExceptionजिसका उपयोग अनपेक्षित जानकारी रिपोर्ट करने के लिए किया जाता है:

partial interface IValidationError { }

abstract partial class ValidationException : System.Exception
{
    public abstract IValidationError[] ValidationErrors { get; }
}

( System.Component.DataAnnotationsनाम स्थान कुछ ऐसा ही करता है।)

इन प्रकारों को निम्नानुसार नियोजित किया जा सकता है:

partial interface IFoo { }  // an immutable type

partial interface IFooBuilder  // mutable counterpart to prepare instances of above type
{
    bool IsValid(out IValidationError[] validationErrors);  // true if no validation error occurs
    IFoo Build();  // throws ValidationException if !IsValid(…)
}

अब मैं सोच रहा हूँ, क्या मैं इसे सरल नहीं बना सकता:

partial class ValidationError : System.Exception { }  // = IValidationError + ValidationException

partial interface IFoo { }  // (unchanged)

partial interface IFooBuilder
{
    bool IsValid(out ValidationError[] validationErrors);
    IFoo Build();  // may throw ValidationError or sth. like AggregateException<ValidationError>
}

प्रश्न: इन दो अलग-अलग तरीकों के फायदे और नुकसान क्या हैं?


यदि आप दो अलग-अलग उत्तरों की तलाश कर रहे हैं, तो आपको दो अलग-अलग प्रश्न पूछने चाहिए। उनका संयोजन सिर्फ इतना है कि जवाब देने के लिए बहुत कठिन है।
बोबसन

2
@ बोबसन: मैं इन दो प्रश्नों को पूरक के रूप में देखता हूं: पूर्व प्रश्न को व्यापक संदर्भ में मुद्दे के सामान्य संदर्भ को परिभाषित करने के लिए माना जाता है, जबकि बाद वाला विशिष्ट जानकारी मांगता है जो पाठकों को अपने निष्कर्ष निकालने की अनुमति देनी चाहिए। एक उत्तर में दोनों प्रश्नों के अलग-अलग, स्पष्ट उत्तर नहीं देने होते; जवाब "इन-बीच" सिर्फ स्वागत के रूप में हैं।
स्टैक

5
मैं किसी चीज़ पर अस्पष्ट हूँ: यदि आप इसे फेंकने नहीं जा रहे हैं, तो अपवाद से वैधता प्राप्त करने का क्या कारण है?
पीडीआर

@pdr: AggregateExceptionइसके बजाय फेंकने के मामले में आपका क्या मतलब है ? अच्छी बात।
स्टैक

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

जवाबों:


31

क्या कोई ऐसी वैध परिस्थितियाँ हैं जहाँ अपवादों को फेंका और पकड़ा नहीं जाता है, लेकिन बस एक विधि से लौटा दिया जाता है और फिर त्रुटि वस्तुओं के रूप में चारों ओर से गुजरता है?

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

क्या यह अपवाद वस्तुओं को वापस करने के लिए एक फ़ंक्शन के लिए वैध है?

पूर्ण रूप से। यहां उन उदाहरणों की एक छोटी सूची दी गई है, जहां यह उपयुक्त हो सकता है:

  • एक अपवाद कारखाना।
  • एक संदर्भ ऑब्जेक्ट जो रिपोर्ट करता है कि अपवाद का उपयोग करने के लिए तैयार के रूप में पिछली त्रुटि थी।
  • एक फ़ंक्शन जो पहले पकड़ा गया अपवाद रखता है।
  • एक तृतीय-पक्ष एपीआई जो एक आंतरिक प्रकार का अपवाद बनाता है।

क्या यह बुरा नहीं है?

एक अपवाद को फेंकना इस तरह है: "जेल जाना है। पास मत जाओ!" बोर्ड खेल एकाधिकार में। यह एक संकलक को उस स्रोत कोड को निष्पादित किए बिना सभी स्रोत कोड को पकड़ने के लिए ऊपर कूदने के लिए कहता है। यह बग, त्रुटियों की रिपोर्टिंग या रोक के साथ करने के लिए कुछ भी नहीं है। मैं एक फ़ंक्शन के लिए "सुपर रिटर्न" बयान के रूप में एक अपवाद को फेंकने के बारे में सोचना पसंद करता हूं। यह मूल कॉलर की तुलना में कहीं अधिक तक कोड का निष्पादन करता है।

यहां महत्वपूर्ण बात यह समझना है कि अपवाद का वास्तविक मूल्य try/catchपैटर्न में है, और अपवाद वस्तु का तात्कालिकता नहीं है। अपवाद वस्तु केवल एक राज्य संदेश है।

आपके प्रश्न में आप इन दो चीजों के उपयोग को भ्रमित करने वाले प्रतीत होते हैं: अपवाद के एक हैंडलर के लिए कूदना, और त्रुटि राज्य अपवाद का प्रतिनिधित्व करता है। सिर्फ इसलिए कि आपने एक त्रुटि स्थिति ली और इसे अपवाद में लपेटने का मतलब यह नहीं है कि आप try/catchपैटर्न या इसके लाभों का पालन ​​कर रहे हैं ।


4
"अगर इसे कभी नहीं फेंका जाता है तो यह अपवाद नहीं है। यह एक Exceptionवर्ग से प्राप्त वस्तु है, लेकिन व्यवहार का पालन नहीं करता है।" - और यह वास्तव में मुद्दा है: क्या यह एक वैध Exceptionवस्तु का उपयोग करने के लिए वैध है ऐसी स्थिति में जहां यह बिल्कुल भी नहीं फेंका जाएगा, न तो वस्तु के निर्माता द्वारा, न ही किसी भी कॉलिंग विधि द्वारा; जहां यह केवल "सुपर रिटर्न" नियंत्रण प्रवाह के बिना, एक "राज्य संदेश" के रूप में कार्य करता है? या क्या मैं एक अनिर्दिष्ट try/ catch(Exception)अनुबंध का इतनी बुरी तरह से उल्लंघन कर रहा हूं कि मुझे ऐसा कभी नहीं करना चाहिए, और इसके बजाय एक अलग, गैर- Exceptionप्रकार का उपयोग करना चाहिए ?
स्टैक

10
@stakx प्रोग्रामर के पास अन्य प्रोग्रामर को भ्रमित करने वाले काम करने के लिए हैं, लेकिन तकनीकी रूप से गलत नहीं हैं। इसलिए मैंने कहा कि यह शब्दार्थ था। कानूनी जवाब है कि Noआप कोई अनुबंध नहीं तोड़ रहे हैं। यह popular opinionहोगा कि आपको ऐसा नहीं करना चाहिए। प्रोग्रामिंग उन उदाहरणों से भरा है जहां आपका स्रोत कोड कुछ भी गलत नहीं करता है, लेकिन हर कोई इसे नापसंद करता है। स्रोत कोड को हमेशा लिखा जाना चाहिए ताकि यह स्पष्ट हो कि इरादा क्या है। क्या आप वास्तव में इस तरह से एक अपवाद का उपयोग करके किसी अन्य प्रोग्रामर की मदद कर रहे हैं? यदि हाँ, तो ऐसा करें। यदि यह नापसंद है तो आश्चर्यचकित न हों।
रिएक्टगुलर

@cgTag इटैलिक के लिए इनलाइन कोड ब्लॉक का आपका उपयोग मेरे दिमाग को चोट पहुँचाता है ..
Frayt

51

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

एक संभावित उपयोग-मामला एक फ़ंक्शन हो सकता है जो HTTP प्रतिक्रिया कोड को अपवादों में बदल देता है:

Exception analyzeHttpError(int errorCode) {
    if (errorCode < 400) {
         throw new NotAnErrorException();
    }
    switch (errorCode) {
        case 403:
             return new ForbiddenException();
        case 404:
             return new NotFoundException();
        case 500:
             return new InternalServerErrorException();
        …
        default:
             throw new UnknownHttpErrorCodeException(errorCode);
     }
}

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


यह संकलक को कोड प्रवाह को समझने में भी मदद करता है: यदि कोई विधि कभी सही तरीके से नहीं लौटती है (क्योंकि यह "वांछित" अपवाद को फेंकता है) और संकलक को इसके बारे में पता नहीं है, तो आपको returnकंपाइलर स्टॉप शिकायत करने के लिए कभी-कभी अति-आवश्यक बयानों की आवश्यकता हो सकती है ।
जोआचिम सॉउर

@ जोचिमसौर यस। एक से अधिक बार मैं चाहूंगा कि वे C # के लिए "कभी नहीं" का एक रिटर्न प्रकार जोड़ेंगे - यह इंगित करेगा कि फ़ंक्शन को फेंकने से बाहर निकलना चाहिए, इसमें रिटर्न डालना एक त्रुटि है। कभी-कभी आपके पास कोड होता है जिसका एकमात्र काम अपवाद के रूप में होता है।
लोरेन Pechtel

2
@LorenPechtel एक फ़ंक्शन जो कभी नहीं लौटता है वह फ़ंक्शन नहीं है। यह एक टर्मिनेटर है। किसी फ़ंक्शन को कॉल करें जैसे कॉलिंग स्टैक को साफ़ करता है। यह कॉलिंग के समान है System.Exit()। फ़ंक्शन कॉल के बाद का कोड निष्पादित नहीं किया गया है। यह एक समारोह के लिए एक अच्छे डिजाइन पैटर्न की तरह आवाज नहीं करता है।
रिएक्टगुलर

5
@MathewFoscarini एक ऐसे वर्ग पर विचार करें जिसमें कई विधियाँ हैं जो समान तरीकों से त्रुटि कर सकते हैं। आप कुछ राज्य की जानकारी को अपवाद के भाग के रूप में डंप करना चाहते हैं, यह इंगित करने के लिए कि जब वह उफान पर गया था तो वह क्या चबा रहा था। आप DRY की वजह से कोडिंग की एक कॉपी चाहते हैं। यह या तो एक फ़ंक्शन को कॉल करता है जो सुंदरिंग-अप करता है और आपके थ्रो में परिणाम का उपयोग करता है या इसका मतलब है कि ऐसा फ़ंक्शन जो पहले से बना हुआ पाठ बनाता है और फिर इसे फेंकता है। मैं आमतौर पर उत्तरार्द्ध को बेहतर पाता हूं।
लॉरेन Pechtel

1
@LorenPechtel आह, हाँ मैंने वह भी किया है। अच्छा अब मैं समझ गया।
रिएक्टगुलर

5

वैचारिक रूप से, यदि अपवाद ऑब्जेक्ट ऑपरेशन का अपेक्षित परिणाम है, तो हाँ। हालांकि, मैं जिन मामलों के बारे में सोच सकता हूं, उनमें हमेशा कुछ बिंदु पर थ्रो-कैच शामिल होते हैं:

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

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


मुझे नहीं लगता कि किसी भी उल्लेखनीय लोगों ने "कोशिश" पैटर्न पर इस तरह की भिन्नता की वकालत करते हुए देखा, लेकिन एक बूलियन को वापस करने का "अनुशंसित" दृष्टिकोण बहुत ही निराशाजनक लगता है। मुझे लगता है कि अमूर्त OperationResultवर्ग के लिए बेहतर हो सकता है , एक boolसंपत्ति "सफल" के साथ, एक GetExceptionIfAnyविधि, और एक AssertSuccessfulविधि (जो GetExceptionIfAnyअगर गैर-अशक्त से अपवाद को फेंक देगी )। GetExceptionIfAnyसंपत्ति के बजाय एक विधि होने से उन मामलों के लिए स्थिर अपरिवर्तनीय त्रुटि वस्तुओं के उपयोग की अनुमति होगी जहां कहने के लिए बहुत उपयोगी नहीं था।
Supercat

5

मान लें कि आपने कुछ थ्रेड पूल में किसी कार्य को अंजाम दिया है। यदि यह कार्य अपवाद छोड़ता है, तो यह अलग धागा है इसलिए आप इसे नहीं पकड़ते हैं। थ्रेड जहां इसे निष्पादित किया गया था बस मर जाते हैं।

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

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

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

सामान्य तौर पर, मैं अपवाद बनाने से दूर रहूंगा और इसे कभी भी नहीं फेंकूंगा (जब तक कि प्रदर्शन के अनुकूलन के बाद इसे टोंटी के रूप में इंगित नहीं किया जाता)। कम से कम जावा में, जहां अपवाद निर्माण महंगा है (स्टैक ट्रेस)। C # में यह संभावना है, लेकिन IMO अपने आश्चर्यजनक है और इस तरह से बचा जाना चाहिए।


यह अक्सर त्रुटि श्रोता वस्तुओं के साथ भी होता है। एक कतार कार्य को निष्पादित करेगी, किसी भी अपवाद को पकड़ेगी, फिर उस अपवाद को त्रुटि श्रोता को पास कर दें। यह आमतौर पर कार्य थ्रेड को मारने के लिए समझ में नहीं आता है जो इस मामले में नौकरी के बारे में ज्यादा नहीं जानता है। इस तरह का विचार जावा एपीआई में भी बनाया गया है जहां एक धागा दूसरे से अपवादों को प्राप्त कर सकता है: docs.oracle.com/javase/1.5.0/docs/api/java/lang/…
लांस नानक

1

यह आपके डिजाइन पर निर्भर करता है, आम तौर पर मैं एक फोन करने वाले को अपवाद नहीं लौटाता, बल्कि मैं उन्हें फेंक देता और उसे छोड़ देता। आमतौर पर कोड को जल्दी और तेजी से विफल करने के लिए लिखा जाता है। उदाहरण के लिए किसी फ़ाइल को खोलने और उसे संसाधित करने के मामले पर विचार करें (यह C # PsuedoCode है):

        private static void ProcessFileFailFast()
        {
            try
            {
                using (var file = new System.IO.StreamReader("c:\\test.txt"))
                {
                    string line;
                    while ((line = file.ReadLine()) != null)
                    {
                        ProcessLine(line);
                    }
                }
            }
            catch (Exception ex) 
            {
                LogException(ex);
            }
        }

        private static void ProcessLine(string line)
        {
            //TODO:  Process Line
        }

        private static void LogException(Exception ex)
        {
            //TODO:  Log Exception
        }

इस मामले में, हम त्रुटि दर्ज करेंगे और खराब रिकॉर्ड का सामना करते ही फाइल को संसाधित करना बंद कर देंगे।

लेकिन कहते हैं कि आवश्यकता यह है कि हम फ़ाइल को संसाधित करना जारी रखना चाहते हैं, भले ही एक या अधिक लाइनों में त्रुटि हो। कोड कुछ इस तरह दिखना शुरू हो सकता है:

    private static void ProcessFileFailAndContinue()
    {
        try
        {
            using (var file = new System.IO.StreamReader("c:\\test.txt"))
            {
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    Exception ex = ProcessLineReturnException(line);
                    if (ex != null)
                    {
                        _Errors.Add(ex);
                    }
                }
            }

            //Do something with _Errors Here
        }
        //Catch errors specifically around opening the file
        catch (System.IO.FileNotFoundException fnfe) 
        { 
            LogException(fnfe);
        }    
    }

    private static Exception ProcessLineReturnException(string line)
    {
        try
        {
            //TODO:  Process Line
        }
        catch (Exception ex)
        {
            LogException(ex);
            return ex;
        }

        return null;
    }

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

आपके सत्यापन उदाहरण के लिए, मैं शायद एक अपवाद वर्ग से विरासत में नहीं मिला हूं या अपवाद नहीं फेंकूंगा क्योंकि सत्यापन त्रुटियां काफी सामान्य हो सकती हैं। किसी अपवाद को फेंकने के बजाय किसी ऑब्जेक्ट को वापस करने के लिए यह ओवरहेड कम होगा यदि मेरे 50% उपयोगकर्ता पहले प्रयास पर एक फॉर्म को सही ढंग से भरने में विफल रहते हैं।


1

प्रश्न: क्या कोई ऐसी वैध परिस्थितियाँ हैं जहाँ अपवादों को फेंका और पकड़ा नहीं जाता है, लेकिन बस एक विधि से लौटा दिया जाता है और फिर त्रुटि वस्तुओं के रूप में चारों ओर से गुजरता है?

हाँ। उदाहरण के लिए, मुझे हाल ही में एक ऐसी स्थिति का सामना करना पड़ा जहां मैंने पाया कि ASMX वेब सर्विस डोनट में अपवादों को परिणामी SOAP संदेश में एक तत्व शामिल है, इसलिए मुझे इसे उत्पन्न करना पड़ा।

उदाहरण कोड:

Public Sub SomeWebMethod()
    Try
        ...
    Catch ex As Exception
        Dim soapex As SoapException = Me.GenerateSoapFault(ex)
        Throw soapex
    End Try
End Sub

Private Function GenerateSoapFault(ex As Exception) As SoapException
    Dim document As XmlDocument = New XmlDocument()
    Dim faultDetails As XmlNode = document.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace)
    faultDetails.InnerText = ex.Message
    Dim exceptionType As String = ex.GetType().ToString()
    Dim soapex As SoapException = New SoapException("SoapException", SoapException.ClientFaultCode, Context.Request.Url.ToString, faultDetails)
    Return soapex
End Function

1

अधिकांश भाषाओं (afaik) में, अपवाद कुछ जोड़े गए उपहारों के साथ आते हैं। अधिकतर, वर्तमान स्टैक ट्रेस का एक स्नैपशॉट ऑब्जेक्ट में संग्रहीत होता है। यह डिबगिंग के लिए अच्छा है, लेकिन इसमें मेमोरी निहितार्थ भी हो सकते हैं।

जैसा कि @ThinkingMedia ने पहले ही कहा था, आप वास्तव में एक त्रुटि ऑब्जेक्ट के रूप में अपवाद का उपयोग कर रहे हैं।

आपके कोड उदाहरण में, ऐसा लगता है कि आप मुख्य रूप से कोड के पुन: उपयोग और रचना से बचने के लिए ऐसा करते हैं। मुझे नहीं लगता कि ऐसा करने का यह एक अच्छा कारण है।

स्टैक ट्रेस के साथ आपको एक त्रुटि वस्तु देने के लिए भाषा को धोखा देने का एक अन्य संभावित कारण होगा। यह आपकी त्रुटि हैंडलिंग कोड को अतिरिक्त प्रासंगिक जानकारी देता है।

दूसरी ओर, हम मान सकते हैं कि स्टैक ट्रेस को आसपास रखने से मेमोरी की लागत होती है। उदाहरण के लिए, यदि आप इन वस्तुओं को कहीं एकत्र करना शुरू करते हैं, तो आप एक अप्रिय स्मृति प्रभाव देख सकते हैं। बेशक यह काफी हद तक इस बात पर निर्भर करता है कि संबंधित भाषा / इंजन में स्टैक के निशान कैसे लागू होते हैं।

तो, क्या यह एक अच्छा विचार है?

अब तक मैंने इसका इस्तेमाल या सिफारिश करते हुए नहीं देखा है। लेकिन इसका ज्यादा मतलब नहीं है।

सवाल यह है: क्या स्टैक ट्रेस वास्तव में आपकी त्रुटि से निपटने के लिए उपयोगी है? या अधिक आम तौर पर, आप डेवलपर या व्यवस्थापक को कौन सी जानकारी प्रदान करना चाहते हैं?

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


-4

इसका जवाब है हाँ। Http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exception देखें और अपवादों पर Google की C ++ शैली मार्गदर्शिका के लिए तीर खोलें। आप वहाँ उन तर्कों को देख सकते हैं जो वे खिलाफ तय करते थे, लेकिन कहते हैं कि अगर उन्हें इसे फिर से करना पड़ता है, तो वे संभवतः इसके लिए फैसला करेंगे।

हालांकि यह ध्यान देने योग्य है कि गो भाषा समान कारणों से या तो अपवाद का उपयोग नहीं करती है।


1
क्षमा करें, लेकिन मुझे समझ में नहीं आता है कि ये दिशानिर्देश प्रश्न का उत्तर देने में कैसे मदद करते हैं: वे बस सलाह देते हैं कि अपवाद से निपटने को पूरी तरह से टाला जाए। यह वह नहीं है जिसके बारे में मैं पूछ रहा हूं; मेरा सवाल यह है कि क्या ऐसी स्थिति में त्रुटि स्थिति का वर्णन करने के लिए अपवाद प्रकार का उपयोग करना वैध है जहां परिणामी अपवाद वस्तु को कभी भी फेंका नहीं जाएगा। इन दिशानिर्देशों में इसके बारे में कुछ भी नहीं प्रतीत होता है।
स्टैक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.