Ce face runCatching
runCatching { ... } rulează blocul și returnează un Result: Success(valoare) dacă totul a mers bine sau Failure(excepție) dacă blocul a aruncat o excepție. Este un try/catch sub formă de valoare, pe care o poți păstra, transmite și transforma.
Din Result scoți valoarea în trei feluri: getOrNull() dă valoarea sau null la eroare; getOrElse { e -> ... } dă valoarea sau rezultatul blocului, care primește excepția; getOrThrow() dă valoarea sau aruncă din nou excepția. Mai poți verifica isSuccess, isFailure și exceptionOrNull().
Atenție: runCatching prinde orice Throwable, inclusiv erori grave precum OutOfMemoryError. Pentru o singură excepție așteptată, un try/catch pe tipul exact este mai precis.
Parametri
| Parametru | Descriere |
|---|---|
block: () -> R |
Codul care poate arunca o excepție. |
onFailure: (Throwable) -> R |
La getOrElse: ce valoare se folosește la eroare; primește excepția. |
Ce returnează
runCatching: un Result<R>. getOrNull: valoarea sau null. getOrElse: valoarea sau valoarea de rezervă. getOrThrow: valoarea sau aruncă excepția.
Exemple
Exemplul 1: Success și Failure
Primul text se convertește fără probleme; al doilea aruncă NumberFormatException, care ajunge în Result în loc să oprească programul.
fun main() {
val bun = runCatching { "125".toInt() }
val rau = runCatching { "12a".toInt() }
println(bun)
println(rau)
println("${bun.isSuccess} ${rau.isFailure}")
println(rau.exceptionOrNull()?.message)
}
Rezultat
Success(125)
Failure(java.lang.NumberFormatException: For input string: "12a")
true true
For input string: "12a"
Exemplul 2: getOrNull, getOrElse și getOrThrow
Pentru textul greșit, getOrNull dă null, getOrElse dă valoarea de rezervă 0.0, exceptionOrNull arată excepția, iar getOrThrow aruncă excepția mai departe, unde o prindem.
fun main() {
val texte = listOf("19.99", "gratis")
for (t in texte) {
val pret = runCatching { t.toDouble() }
println("getOrNull: ${pret.getOrNull()}")
println("getOrElse: ${pret.getOrElse { 0.0 }}")
println("excepția: ${pret.exceptionOrNull()?.let { it::class.simpleName }}")
try {
println("getOrThrow: ${pret.getOrThrow()}")
} catch (e: NumberFormatException) {
println("getOrThrow a aruncat: ${e.message}")
}
}
}
Rezultat
getOrNull: 19.99
getOrElse: 19.99
excepția: null
getOrThrow: 19.99
getOrNull: null
getOrElse: 0.0
excepția: NumberFormatException
getOrThrow a aruncat: For input string: "gratis"
Greșeli frecvente
- Folosești runCatching peste tot și ignori rezultatul. Erorile dispar fără urmă; verifică sau afișează excepția.
- Crezi că
getOrElse(0)primește valoarea direct. Primește un bloc:getOrElse { 0 }. Pentru o valoare fixă există șigetOrDefault(0). - Folosești runCatching în corutine fără grijă: prinde și
CancellationException, care ar trebui să oprească corutina.
Comenzi înrudite
Result.onSuccess: Rulează o acțiune doar dacă Result a reușit (onSuccess) sau doar dacă a eșuat (onFailure); ambele returnează același Result.Result.map: map transformă valoarea unui Result reușit și lasă eroarea neschimbată; fold dă o valoare finală din ambele cazuri.require: Verifică argumentele unei funcții și aruncă IllegalArgumentException dacă nu sunt bune; requireNotNull cere o valoare diferită de null.String.toInt: Transformă un text în număr întreg; toInt aruncă excepție la text invalid, toIntOrNull returnează null.