Swift में त्रुटि प्रबंधन: try/catch और भी बहुत कुछ
iOS और macOS के लिए विकास में विश्वसनीय त्रुटि प्रबंधन की आवश्यकता होती है। Swift throws, try, catch और do कीवर्ड पर आधारित एक शक्तिशाली और सुरुचिपूर्ण त्रुटि प्रबंधन तंत्र प्रदान करता है। इस लेख में, हम सीखेंगे कि त्रुटियों को सही तरीके से कैसे संभालें, पठनीय कोड कैसे लिखें और सामान्य गलतियों से कैसे बचें।
1. मूल बातें: Error प्रोटोकॉल और throws कीवर्ड
Swift में किसी भी त्रुटि को Error प्रोटोकॉल का पालन करना चाहिए। आमतौर पर इसके लिए एनुम (enum) का उपयोग किया जाता है:
enum NetworkError: Error { case badURL case noData case decodingFailed(String)}एक फ़ंक्शन जो त्रुटि उत्पन्न कर सकता है, उसे throws कीवर्ड से चिह्नित किया जाता है:
func fetchUser(from urlString: String) throws -> User { guard let url = URL(string: urlString) else { throw NetworkError.badURL } // ... अनुरोध तर्क}अब ऐसे फ़ंक्शन को कॉल करते समय, कंपाइलर आपको संभावित त्रुटि को संभालने के लिए बाध्य करेगा।
2. do-catch संरचना: त्रुटियों को पकड़ना
सबसे सामान्य प्रबंधन विधि do-catch ब्लॉक है। आप संभावित खतरनाक कोड को do में रखते हैं, और catch में त्रुटि को संभालते हैं:
do { let user = try fetchUser(from: "https://api.example.com/user") print("User loaded: \\(user.name)")} catch NetworkError.badURL { print("अमान्य URL")} catch NetworkError.noData { print("सर्वर ने डेटा वापस नहीं किया")} catch NetworkError.decodingFailed(let message) { print("डिकोडिंग त्रुटि: \\(message)")} catch { print("अज्ञात त्रुटि: \\(error.localizedDescription)")}महत्वपूर्ण: अंतिम catch ब्लॉक बिना किसी विशिष्ट प्रकार के सभी शेष त्रुटियों को पकड़ता है - इसे हमेशा जोड़ना चाहिए।
2.1. catch में पैटर्न मिलान
आप अधिक जटिल शर्तों का उपयोग कर सकते हैं:
do { let result = try riskyOperation()} catch let error as NetworkError where error == .badURL { print("URL में समस्या")} catch { print(error)}3. विकल्प: try? और try!
हमेशा पूर्ण प्रबंधन की आवश्यकता नहीं होती। Swift दो सरलीकृत दृष्टिकोण प्रदान करता है:
3.1. try? — वैकल्पिक मान
यदि त्रुटि गंभीर नहीं है, तो परिणाम को वैकल्पिक में बदला जा सकता है। विफलता पर फ़ंक्शन nil लौटाएगा:
let user = try? fetchUser(from: "https://example.com/user")// user का प्रकार User? है — त्रुटि पर nilउन स्थितियों के लिए आदर्श जहाँ त्रुटि को अनदेखा किया जा सकता है (जैसे, अवतार लोड करना)।
3.2. try! — अनिवार्य निष्पादन
try! का उपयोग केवल तब करें जब आप पूरी तरह से आश्वस्त हों कि कोई त्रुटि नहीं होगी। अन्यथा — एप्लिकेशन क्रैश हो जाएगा:
let user = try! fetchUser(from: "https://valid-url.com/user")// यदि URL अमान्य है — एप्लिकेशन क्रैश हो जाएगाtry! का उपयोग परीक्षणों में या उन स्थितियों में करें जहाँ प्रोग्राम के तर्क के अनुसार विफलता असंभव है।
4. उन्नत तकनीकें: rethrows और deferred
4.1. उच्च-क्रम फ़ंक्शन के लिए rethrows
यदि आपका फ़ंक्शन एक क्लोज़र स्वीकार करता है जो त्रुटि उत्पन्न कर सकता है, तो rethrows का उपयोग करें। यदि क्लोज़र त्रुटि नहीं उत्पन्न करता है तो यह आपको अपने फ़ंक्शन को throws के रूप में चिह्नित करने से बचाता है:
func process(_ closure: () throws -> Void) rethrows { try closure()}
// बिना throws-क्लोज़र के कॉल — do-catch की आवश्यकता नहींprocess { print("बिना त्रुटियों के") }
// throws-क्लोज़र के साथ कॉल — प्रबंधन की आवश्यकताtry process { throw NetworkError.noData }4.2. deferred: गारंटीकृत सफाई
defer ब्लॉक फ़ंक्शन के किसी भी समाप्ति (सफलता या त्रुटि) पर निष्पादित होता है। फ़ाइलों को बंद करने या संसाधनों को मुक्त करने के लिए उपयुक्त है।