C# में उन्नत त्रुटि प्रबंधन: बुनियादी try/catch से औद्योगिक पैटर्न तक
\n\nत्रुटि प्रबंधन केवल अपवादों को रोकना नहीं है, बल्कि विश्वसनीय सिस्टम डिज़ाइन करने की कला है। C# (.NET) में, डेवलपर अक्सर try/catch संरचना तक ही सीमित रहते हैं, लेकिन प्लेटफ़ॉर्म कहीं अधिक शक्तिशाली तंत्र प्रदान करता है। इस लेख में, हम उन्नत तकनीकों पर चर्चा करेंगे: अपवाद फ़िल्टर से लेकर पुनर्प्राप्ति पैटर्न और त्रुटि संदर्भ स्थानांतरण तक।
1. अपवाद फ़िल्टर: स्टब्स के बजाय सटीकता
\n\nC# 6.0 में आए अपवाद फ़िल्टर (Exception Filters), अपवाद को दोबारा फेंके बिना catch ब्लॉक में प्रवेश करने की शर्त निर्दिष्ट करने की अनुमति देते हैं। यह ब्लॉक के अंदर if वाले क्लासिक दृष्टिकोण की तुलना में कहीं अधिक स्वच्छ है।
try\n{\n // कोड जो अपवाद फेंक सकता है\n var result = ProcessData(input);\n}\ncatch (CustomException ex) when (ex.ErrorCode == 1001)\n{\n // केवल कोड 1001 वाली त्रुटियों को संभालें\n Log.Error($"गंभीर त्रुटि: {ex.Message}");\n throw; // यदि आवश्यक हो तो आगे भेजें\n}\ncatch (CustomException ex) when (ex.IsRecoverable)\n{\n // पुनर्प्राप्त करने योग्य त्रुटि — लॉग करें और जारी रखें\n Log.Warning($"पुनर्प्राप्त करने योग्य त्रुटि: {ex.Message}");\n RetryOperation();\n}\n\nलाभ:
\n- \n
- फ़िल्टरिंग के लिए दोबारा
throwकी आवश्यकता नहीं है। \n - पठनीयता और प्रदर्शन में सुधार होता है (कॉल स्टैक खराब नहीं होता)। \n
- विभिन्न शर्तों के साथ कई
catchब्लॉक को जोड़ा जा सकता है। \n
2. "पुनर्प्राप्ति" पैटर्न (Retry) और Polly
\n\nसभी त्रुटियाँ घातक नहीं होतीं। अस्थायी विफलताओं (नेटवर्क समस्याएँ, DB लॉक) के लिए पुनः प्रयास पैटर्न का उपयोग करें। C# के अंतर्निहित साधन सीमित हैं, इसलिए Polly लाइब्रेरी की अनुशंसा की जाती है।
\n\nusing Polly;\nusing Polly.Retry;\n\n// पुनः प्रयास नीति परिभाषित करें\nAsyncRetryPolicy retryPolicy = Policy\n .Handle<HttpRequestException>() // केवल HTTP त्रुटियों को संभालें\n .WaitAndRetryAsync(\n 3, // प्रयासों की संख्या\n retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // एक्सपोनेंशियल देरी\n onRetry: (exception, timeSpan, retryCount, context) =>\n {\n Log.Warning($"प्रयास {retryCount} विफल रहा। {timeSpan.Seconds} सेकंड में पुनः प्रयास।");\n });\n\n// नीति लागू करें\nawait retryPolicy.ExecuteAsync(async () =>\n{\n var response = await httpClient.GetAsync("https://api.example.com/data");\n response.EnsureSuccessStatusCode();\n});\n\nमहत्वपूर्ण: अनंत रेट्री का उपयोग न करें। हमेशा अधिकतम प्रयास निर्धारित करें और कैस्केडिंग विफलताओं से सिस्टम की सुरक्षा के लिए Circuit Breaker का उपयोग करें।
\n\n3. अपवादों का सही स्थानांतरण: throw बनाम throw ex
\n\nसबसे आम गलतियों में से एक है कॉल स्टैक का खो जाना। डिबगिंग के लिए throw और throw ex के बीच का अंतर महत्वपूर्ण है।
try\n{\n // ...\n}\ncatch (Exception ex)\n{\n // गलत: मूल स्टैक खो देते हैं\n // throw ex; \n\n // सही: स्टैक को संरक्षित करते हैं\n throw;\n\n // या: मूल को खोए बिना संदर्भ जोड़ें\n // throw new ApplicationException("मॉड्यूल X में त्रुटि", ex);\n}\n\nयदि संदर्भ जोड़ने की आवश्यकता है, तो थ्रेड्स के बीच फेंकते समय स्टैक को सटीक रूप से संरक्षित करने के लिए ExceptionDispatchInfo (नेमस्पेस System.Runtime.ExceptionServices से) का उपयोग करें।
ExceptionDispatchInfo.Capture(exception).Throw(); // मूल स्टैक को संरक्षित करता है\n\n4. कस्टम अपवाद और त्रुटि संदर्भ
\n\nमानक अपवाद अक्सर व्यावसायिक संदर्भ नहीं रखते। अतिरिक्त गुणों के साथ अपने स्वयं के अपवाद वर्ग बनाएँ।
\n\npublic class PaymentProcessingException : Exception\n{\n public int OrderId { get; }\n public dec