Try-Catch एक अपवाद पकड़ने वाली संरचना है जो संभावित खतरनाक कोड को एक सुरक्षित ब्लॉक में निष्पादित करने और प्रोग्राम को क्रैश हुए बिना त्रुटियों को सही ढंग से संभालने की अनुमति देती है। try ब्लॉक में वह कोड होता है जो अपवाद फेंक सकता है, catch उसे पकड़ता है और पुनर्प्राप्ति तर्क निष्पादित करता है। Apple Swift Documentation (2026) के अनुसार, finally ब्लॉक चाहे अपवाद फेंका गया हो या नहीं, निष्पादित होता है, जिससे संसाधन मुक्ति सुनिश्चित होती है।
मुख्य बातें
Try-Catch एक मौलिक संरचनात्मक अपवाद प्रबंधन संरचना है जो अधिकांश आधुनिक प्रोग्रामिंग भाषाओं में मौजूद है। यह तीन ब्लॉकों से बनी होती है: try (खतरनाक कोड निष्पादित करने का प्रयास), catch (अपवाद को पकड़ना और संभालना) और वैकल्पिक finally (समापन)। संरचना का विचार व्यावसायिक तर्क को त्रुटि प्रबंधन तर्क से अलग करना है, जिससे कोड अधिक पठनीय और पूर्वानुमानित हो जाता है।
इस अवधारणा को पहली बार C++ में try/catch के रूप में लागू किया गया था, फिर Java, C#, Swift, Kotlin, Dart, Python, JavaScript और अन्य भाषाओं द्वारा अपनाया गया। प्रत्येक भाषा अपनी विशेषताएँ जोड़ती है: Swift में catch ब्लॉक को व्यापक होना चाहिए, Kotlin में try-catch एक एक्सप्रेशन हो सकता है, Dart में स्ट्रीम संसाधनों के लिए finally अनिवार्य है। मतभेदों के बावजूद, मूल सिद्धांत एक ही है: त्रुटि को वैश्विक रूप से नहीं, बल्कि घटना स्थल के जितना संभव हो उतना करीब संभाला जाता है।
Try-Catch का उपयोग मोबाइल डेवलपमेंट में विशेष रूप से महत्वपूर्ण है, जहाँ बाहरी कारक — नेटवर्क हानि, सर्वर से गलत प्रतिक्रिया, अपर्याप्त मेमोरी — लगातार होते रहते हैं। उचित अपवाद प्रबंधन एप्लिकेशन को क्रैश होने से रोकता है और सही UX सुनिश्चित करता है: उपयोगकर्ता अचानक एप्लिकेशन बंद होने के बजाय एक त्रुटि संदेश देखता है। Google Android Kotlin Style Guide (2026) के अनुसार, प्रत्येक फ़ंक्शन जो अपवाद फेंक सकता है, उसे या तो try-catch के माध्यम से इसे संभालना चाहिए या अपने हस्ताक्षर में throws घोषित करना चाहिए।
Try-catch का निष्पादन तंत्र स्टैक अनवाइंडिंग (stack unwinding) पर आधारित है। जब try ब्लॉक के अंदर throw ऑपरेटर के माध्यम से (या सिस्टम त्रुटि के परिणामस्वरूप) एक अपवाद फेंका जाता है, तो सामान्य निष्पादन प्रवाह तुरंत बाधित हो जाता है। निष्पादन उपयुक्त catch ब्लॉक की खोज में कॉल स्टैक में एक स्तर ऊपर चला जाता है। आधुनिक भाषाएँ टाइप मैचिंग तंत्र (type matching) का उपयोग करके फेंके गए अपवाद के प्रकार से मेल खाने वाला catch ढूँढ़ती हैं।
यदि मेल खाने वाला catch मिल जाता है, तो उसका बॉडी निष्पादित होता है, जिसके बाद निष्पादन पूरी try-catch-finally संरचना के बाद जारी रहता है। यदि कोई catch नहीं मिलता है, तो अपवाद स्टैक में और ऊपर बढ़ता है और उच्च स्तर पर संभाला जा सकता है — एक वैश्विक हैंडलर तक, जो मोबाइल एप्लिकेशन में उपयोगकर्ता को त्रुटि संवाद दिखाता है। यदि अपवाद कहीं भी संभाला नहीं जाता है, तो एप्लिकेशन क्रैश हो जाता है। यही कारण है कि एप्लिकेशन स्थिरता के लिए सभी संभावित अपवाद प्रकारों का सही प्रबंधन महत्वपूर्ण है।
fun readUserData(): User {
return try {
val response = api.fetchUser()
parseUser(response)
} catch (e: IOException) {
logError("नेटवर्क त्रुटि", e)
throw AppException("डेटा लोड करने में विफलता")
} catch (e: JsonParseException) {
logError("पार्सिंग त्रुटि", e)
return User.default()
} finally {
closeLoadingIndicator()
}
}
कोड पहले API अनुरोध करने और प्रतिक्रिया को पार्स करने का प्रयास करता है। यदि IOException (नेटवर्क समस्या) होता है, तो अपवाद लॉग किया जाता है और AppException के रूप में वापस फेंका जाता है। यदि JsonParseException होता है — एक डिफ़ॉल्ट उपयोगकर्ता लौटाया जाता है। finally ब्लॉक लोडिंग इंडिकेटर को छिपाने की गारंटी देता है, जिससे स्क्रीन पर UI घटकों के लीक को रोका जा सके।
Swift में, त्रुटि प्रबंधन Error प्रोटोकॉल (पूर्व में ErrorType) के माध्यम से लागू किया गया है। Error के अनुरूप कोई भी प्रकार throw ऑपरेटर के माध्यम से फेंका जा सकता है। जो फ़ंक्शन त्रुटि फेंक सकता है, उसके हस्ताक्षर में throws कीवर्ड से चिह्नित किया जाता है। ऐसे फ़ंक्शन को कॉल करने के लिए try उपसर्ग (स्पष्ट try-catch के लिए), try? (वैकल्पिक परिणाम) या try! (त्रुटि प्रबंधन के बिना बलपूर्वक निष्पादन) की आवश्यकता होती है।
enum NetworkError: Error {
case noConnection
case serverError(code: Int)
case timeout
}
func fetchUser(id: Int) throws -> User {
guard isConnected() else {
throw NetworkError.noConnection
}
let data = try performRequest(path: "/users/\(id)")
return try decodeUser(from: data)
}
do {
let user = try fetchUser(id: 42)
updateUI(user)
} catch NetworkError.noConnection {
showOfflineAlert()
} catch let error as NetworkError {
showError("नेटवर्क " + error.localizedDescription)
} catch {
showGenericError()
}
Enum NetworkError Error प्रोटोकॉल को लागू करता है, तीन केस परिभाषित करता है: noConnection, कोड के साथ serverError और timeout। fetchUser फ़ंक्शन throws से चिह्नित है: पहले कनेक्शन की जाँच करता है, फिर अनुरोध और पार्सिंग करता है। do-catch ब्लॉक में, तीन catch विभिन्न परिदृश्यों को संभालते हैं: विशिष्ट noConnection केस, सामान्य NetworkError प्रकार और अन्य सभी त्रुटियाँ। यह समस्या के प्रकार के आधार पर उपयोगकर्ता को विभिन्न संदेश दिखाने की अनुमति देता है।
Kotlin ने Java से try-catch-finally विरासत में लिया लेकिन एक महत्वपूर्ण अंतर जोड़ा: Kotlin में, try-catch एक एक्सप्रेशन (expression) है, न कि स्टेटमेंट (statement)। इसका मतलब है कि try ब्लॉक या catch ब्लॉक का परिणाम एक वेरिएबल को असाइन किया जा सकता है। try ब्लॉक में अंतिम एक्सप्रेशन सफलता पर परिणाम बन जाता है, catch में अंतिम एक्सप्रेशन — त्रुटि पर। यदि त्रुटि किसी catch द्वारा संभाली नहीं जाती है, तो अपवाद स्टैक में ऊपर बढ़ता है।
sealed class Result<out T> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Throwable) : Result<Nothing>()
}
fun loadData(): Result<List<Item>> {
return try {
val response = api.getItems()
Result.Success(response.toList())
} catch (e: HttpException) {
Log.e("HTTP ", e)
Result.Error(e)
} catch (e: IOException) {
Log.e("नेटवर्क ", e)
Result.Error(e)
}
}
उदाहरण में, sealed class Result एक सफल प्रतिक्रिया या त्रुटि को लपेटता है। loadData फ़ंक्शन try-catch को एक्सप्रेशन के रूप में उपयोग करता है: सफलता पर Result.Success लौटाता है, HttpException या IOException पर — लॉगिंग के साथ Result.Error। यह दृष्टिकोण कॉलर को बिना अपवादों के त्रुटियों को संभालने की अनुमति देता है — Result प्रकार पर when एक्सप्रेशन के माध्यम से। यह Jetpack Compose में StateFlow और collectAsState के माध्यम से विभिन्न UI स्थितियों (Loading, Success, Error) को प्रदर्शित करने के लिए विशेष रूप से सुविधाजनक है।
Dart Java के समान सिंटैक्स के साथ try-catch-finally का समर्थन करता है, लेकिन चर निर्दिष्ट किए बिना अपवाद प्रकार द्वारा फ़िल्टर करने के लिए on-क्लॉज़ के अतिरिक्त के साथ। यह तब सुविधाजनक होता है जब अपवाद की आवश्यकता नहीं होती — केवल उसके प्रकार का तथ्य महत्वपूर्ण होता है। Dart दो पैरामीटर के साथ catch ब्लॉक का भी समर्थन करता है: अपवाद ऑब्जेक्ट और StackTrace, जो पूर्ण कॉल श्रृंखला को लॉग करने के लिए उपयोगी है।
import 'dart:io';
import 'dart:convert';
class UserRepository {
Future<User> fetchUser(String id) async {
try {
final client = HttpClient();
final request = await client.getUrl(
Uri.parse('https://api.example.com/users/$id')
);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
return User.fromJson(json.decode(body));
} on SocketException catch (e, stackTrace) {
log("No internet", e, stackTrace);
throw AppException("Connection failed");
} on FormatException {
throw AppException("Invalid response format");
} finally {
client.close();
}
}
}
SocketException विस्तृत लॉगिंग के लिए अपवाद ऑब्जेक्ट और StackTrace दोनों के साथ पकड़ा जाता है, फिर AppException के रूप में वापस फेंका जाता है। FormatException बिना चर के पकड़ा जाता है — यह जानना पर्याप्त है कि प्रतिक्रिया प्रारूप गलत है। finally ब्लॉक HttpClient को बंद करने की गारंटी देता है, जिससे सॉकेट लीक को रोका जा सके। Flutter में, यह दृष्टिकोण Widget परीक्षण के लिए विशेष रूप से महत्वपूर्ण है, जहाँ State.initState में अनहैंडल किए गए अपवाद पूरे परीक्षण सत्र को क्रैश कर देते हैं।
अनुभवी डेवलपर्स भी try-catch के साथ काम करते समय गलतियाँ करते हैं जो मेमोरी लीक, छिपे हुए बग या एप्लिकेशन के अनुचित व्यवहार का कारण बनती हैं। आइए मोबाइल डेवलपमेंट में पाँच सबसे सामान्य समस्याओं पर नज़र डालें।
खाली catch सबसे खराब प्रथाओं में से एक है। अपवाद को निगल लिया जाता है, एप्लिकेशन गलत स्थिति में काम करना जारी रखता है, और डेवलपर को समस्या के बारे में पता नहीं चलता। हमेशा कम से कम अपवाद को लॉग करें। Kotlin में catch(e: Exception) { Log.e(...) } का उपयोग करें, Swift में — catch { print($0) }। Dart में, न्यूनतम स्वीकार्य catch को debugPrint कॉल करना चाहिए या Crashlytics में लिखना चाहिए।
प्रकारों में अंतर किए बिना catch (Exception e) के माध्यम से सभी अपवादों को पकड़ना अप्रत्याशित त्रुटियों — NullPointerException, OutOfMemoryError, StackOverflowError को छिपा देता है। केवल उन प्रकारों को पकड़ें जिनकी आप अपेक्षा करते हैं और संभाल सकते हैं। बाकी सबके लिए, ऊपर प्रसार की अनुमति दें। मोबाइल डेवलपमेंट में, IOException, TimeoutException, AuthException के लिए विशिष्ट catch उपयोगकर्ता को अधिक सार्थक संदेश देते हैं।
संसाधन — फ़ाइलें, सॉकेट, DB कर्सर, एनिमेशन — finally में या use-ब्लॉक (AutoCloseable) में मुक्त किए जाने चाहिए। डेवलपर्स अक्सर अपवाद होने पर संसाधनों को बंद करना भूल जाते हैं, जिससे लीक होता है। Kotlin में Closeable संसाधनों के लिए .use { } का उपयोग करें, Swift में — defer { }, Dart में — async पैकेज से await using। finally ब्लॉक catch के अंदर अपवाद फेंके जाने पर भी मुक्ति सुनिश्चित करता है।
एसिंक्रोनस कोड में, try-catch अन्य थ्रेड्स से अपवादों को नहीं पकड़ता। Kotlin Coroutines में CoroutineExceptionHandler या SupervisorJob का उपयोग करें। Swift async/await में — Task के अंदर do-catch। Flutter में — वैश्विक पकड़ के लिए runZonedGuarded। इस नियम को अनदेखा करना प्रोडक्शन में दुर्लभ क्रैश का कारण है।
अपवाद प्रबंधन को उपयोगकर्ता इंटरफ़ेस को अनिश्चित काल तक ब्लॉक नहीं करना चाहिए। उपयोगकर्ता को एक विशिष्ट संदेश दिखाएँ और उन्हें ऑपरेशन दोहराने का अवसर दें। Kotlin/Compose में Retry बटन के साथ Snackbar Swift में UIAlertController, Flutter में SnackBar — नेटवर्क या सर्वर त्रुटियों के लिए न्यूनतम पर्याप्त UX। पुनर्प्राप्ति विकल्पों के बिना सामान्य “एक त्रुटि हुई” संवादों से बचें।
अक्सर पूछे जाने वाले प्रश्न
Try-catch त्रुटि प्रबंधन के लिए अपवादों और स्टैक अनवाइंडिंग का उपयोग करता है, जो कई त्रुटियों से निपटने पर प्रदर्शन में महंगा हो सकता है। Result Type एक कंटेनर प्रकार (Success या Failure) है जो बिना स्टैक अनवाइंडिंग के पैटर्न मैचिंग के माध्यम से संभाला जाता है, जो अपेक्षित त्रुटियों के लिए अधिक कुशल है।
Finally आवश्यक है यदि try ब्लॉक संसाधन (फ़ाइलें, सॉकेट, कर्सर) खोलता है जिन्हें बंद करने की आवश्यकता है। यदि कोई संसाधन नहीं खोले जाते हैं, तो finally की आवश्यकता नहीं है। आधुनिक भाषाओं में बिना finally के स्वचालित संसाधन बंद करने के लिए AutoCloseable/use/defer का उपयोग करें। Kotlin और Swift में use-ब्लॉक Closeable ऑब्जेक्ट्स के लिए finally को बदल देता है।
सामान्य प्रवाह में (बिना अपवाद के), try-catch प्रदर्शन को व्यावहारिक रूप से प्रभावित नहीं करता — JVM और Swift कंपाइलर इस मामले को अनुकूलित करते हैं। लेकिन जब अपवाद फेंका जाता है, तो स्टैक अनवाइंडिंग होती है, जो स्टैक गहराई के आधार पर 10–100 μs ले सकती है। प्रवाह नियंत्रण के लिए अपवादों का उपयोग न करें — यह एक एंटी-पैटर्न है।
कोरूटीन में, वैश्विक पकड़ के लिए coroutineScope के अंदर try-catch या CoroutineExceptionHandler का उपयोग करें। SupervisorJob चाइल्ड कोरूटीन के विफल होने पर पैरेंट कोरूटीन को रद्द होने से रोकता है। launch के लिए CoroutineExceptionHandler का उपयोग करें, async के लिए — await() के चारों ओर try-catch।
एकाधिक catch बेहतर हैं: कोड रैखिक रूप से पढ़ा जाता है, प्रत्येक ब्लॉक एक अपवाद प्रकार संभालता है। if-else के साथ एक catch बनाए रखना कठिन है, और नए अपवाद प्रकार को याद करना आसान है। Swift में, enum Error के व्यापक प्रबंधन के लिए एकाधिक catch अनिवार्य हैं, Kotlin में कोई प्रतिबंध नहीं हैं, लेकिन सबसे अच्छा अभ्यास प्रति प्रकार अलग catch है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें