कोटलिन में एक ही समय में कई अपवादों को कैसे पकड़ा जाए


87
try { 

} catch (ex: MyException1, MyException2 ) {
    logger.warn("", ex)
}

या

try { 

} catch (ex: MyException1 | MyException2 ) {
    logger.warn("", ex)
}

नतीजतन, एक संकलन त्रुटि Unresolved reference: MyException2:।

मैं कोटलिन पर एक ही समय में कई अपवाद कैसे पकड़ सकता हूं?

जवाबों:


100

अद्यतन: यदि आप इस सुविधा को कोटलिन में उतरना चाहते हैं तो निम्नलिखित मुद्दे केटी -7128 के लिए वोट करें। धन्यवाद @ क्रिसन

इस सूत्र के अनुसार इस समय यह सुविधा समर्थित नहीं है।

abreslav - JetBrains टीम

फिलहाल नहीं, लेकिन यह मेज पर है

आप हालांकि बहु-कैच की नकल कर सकते हैं:

try {
    // do some work
} catch (ex: Exception) {
    when(ex) {
        is IllegalAccessException, is IndexOutOfBoundsException -> {
            // handle those above
        }
        else -> throw ex
    }
}

2
मैं pdvriezeयहाँ उत्तर की नकल कर रहा हूँ : This certainly works, but is slightly less efficient as the caught exception is explicit to the jvm (so a non-processed exception will not be caught and rethrown which would be the corollary of your solution)
सॉलिडक

1
@IARI elseखंड अनचाहे अपवाद को हटा देता है।
miensol


2
यहां तक ​​कि अगर आप लालित्य और कुरूपता के तर्क को एक तरफ फेंक देते हैं, तो कोटलिन (जो संक्षिप्त होने का दावा करता है) वास्तव में इस मामले में जावा के रूप में 2x के रूप में 2x है
Phileo99

2
Detekt द्वारा ध्वजांकित किया जाता है क्योंकि आप बहुत अधिक सामान्य अपवाद को पकड़ रहे हैं ;-)
kenyee

8

Miensol के जवाब में जोड़ने के लिए : हालांकि कोटलिन में बहु-पकड़ अभी तक समर्थित नहीं है, लेकिन अधिक विकल्प हैं जिनका उल्लेख किया जाना चाहिए।

इसके अलावा try-catch-when, आप मल्टी-कैच की नकल करने के लिए एक विधि भी लागू कर सकते हैं। यहाँ एक विकल्प है:

fun (() -> Unit).catch(vararg exceptions: KClass<out Throwable>, catchBlock: (Throwable) -> Unit) {
    try { 
        this() 
    } catch (e: Throwable) {
        if (e::class in exceptions) catchBlock(e) else throw e
    }
}

और इसके इस्तेमाल से ऐसा लगेगा:

fun main(args: Array<String>) {
    // ...
    {
        println("Hello") // some code that could throw an exception

    }.catch(IOException::class, IllegalAccessException::class) {
        // Handle the exception
    }
}

जैसा कि ऊपर दिखाया गया है (अन्यथा आप "MANY_LAMBDA_EXPRESSION_ARGUMENTS" और अन्य मुद्दे बहुत तेज़ी से चलेंगे) एक कच्चे मेमने का उपयोग करने के बजाय आप एक लंबोदा का उत्पादन करने के लिए एक फ़ंक्शन का उपयोग करना चाहते हैं। कुछ fun attempt(block: () -> Unit) = blockऐसा काम करेगा।

बेशक, आप अपने तर्क को अधिक सुरुचिपूर्ण ढंग से रचने के लिए या सादे पुराने ट्राइ-कैच की तुलना में अलग तरह से व्यवहार करने के लिए लंबोदर के बजाय वस्तुओं को चेन करना चाह सकते हैं।

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


अगर मैं इसे सही ढंग से समझता हूं तो आप अपनी पकड़ में कक्षाएं पास करते हैं, लेकिन परम exceptionsवस्तुओं को ले जाता है।
nllsdfx

आप भयानक आदमी हैं @ आरो, इस विकल्प को प्रदान करने के लिए धन्यवाद
मोचडवी

यह विकल्प अच्छा है, धन्यवाद आरो :) कुछ भी नहीं से बेहतर है। हालाँकि, मुझे उम्मीद है कि वे उस सुविधा को प्राप्त करेंगे, हालांकि मेरा मुद्दा KT-7128 5 साल पहले खोला गया था :-)
zdenda.online

0

Aro से उदाहरण बहुत अच्छा है, लेकिन अगर विरासत में हैं, तो यह जावा की तरह काम नहीं करेगा।

आपके उत्तर ने मुझे इसके लिए एक विस्तार समारोह लिखने के लिए प्रेरित किया। विरासत में मिली कक्षाओं की अनुमति देने के लिए आपको instanceसीधे तुलना करने के बजाय जांच करनी होगी ।

inline fun multiCatch(runThis: () -> Unit, catchBlock: (Throwable) -> Unit, vararg exceptions: KClass<out Throwable>) {
try {
    runThis()
} catch (exception: Exception) {
    val contains = exceptions.find {
        it.isInstance(exception)
    }
    if (contains != null) catchBlock(exception)
    else throw exception
}}

उपयोग करने के तरीके को देखने के लिए, आप यहाँ GitHub पर मेरी लाइब्रेरी में नज़र डाल सकते हैं


"-1" का कारण क्या है? जावा में {...} कैच (X | Y e) {...} आज़माएं। यह उत्तर जावा के व्यवहार की नकल करता है, यह कई अलग-अलग उपप्रकारों के साथ IOException को पकड़ने के लिए उदाहरण के लिए अधिक सुविधाजनक है।
दिमित्री Ovchinnikov
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.