Result.onSuccess în Kotlin

Rulează o acțiune doar dacă Result a reușit (onSuccess) sau doar dacă a eșuat (onFailure); ambele returnează același Result.

Sintaxă
inline fun <T> Result<T>.onSuccess(action: (value: T) -> Unit): Result<T>
inline fun <T> Result<T>.onFailure(action: (exception: Throwable) -> Unit): Result<T>

Ce face Result.onSuccess

onSuccess { valoare -> ... } rulează blocul doar dacă rezultatul este Success, iar onFailure { e -> ... } doar dacă este Failure. Amândouă returnează același Result, așa că le poți pune una după alta într-un lanț, ca pe ramurile unui try/catch.

Sunt potrivite pentru efecte: afișare, log, actualizarea interfeței. Dacă vrei să obții o valoare din ambele cazuri, folosește fold.

Parametri

Parametru Descriere
action: (value: T) -> Unit La onSuccess: ce faci cu valoarea.
action: (exception: Throwable) -> Unit La onFailure: ce faci cu excepția.

Ce returnează

Același Result, neschimbat.

Exemple

Exemplul 1: Mesaje diferite pentru reușită și eșec

fun imparte(a: Int, b: Int): Result<Int> = runCatching { a / b }

fun main() {
    for (b in listOf(4, 0)) {
        imparte(100, b)
            .onSuccess { println("100 / $b = $it") }
            .onFailure { println("100 / $b a eșuat: ${it.message}") }
    }
}

Rezultat

100 / 4 = 25
100 / 0 a eșuat: / by zero

Exemplul 2: Numărarea liniilor greșite dintr-un import

onFailure strânge erorile, iar valorile bune sunt păstrate cu getOrNull.

fun main() {
    val randuri = listOf("Ana;9", "Ion;șapte", "Maria;10", "Dan")
    val erori = mutableListOf<String>()
    val note = randuri.mapNotNull { rand ->
        runCatching { rand.split(";")[1].toInt() }
            .onFailure { erori.add("„$rand”: ${it::class.simpleName}") }
            .getOrNull()
    }
    println("Note citite: $note")
    erori.forEach { println("Eroare la $it") }
}

Rezultat

Note citite: [9, 10]
Eroare la „Ion;șapte”: NumberFormatException
Eroare la „Dan”: IndexOutOfBoundsException

Greșeli frecvente

  • Aștepți ca onSuccess să schimbe valoarea. Returnează același Result; pentru transformare folosește map.
  • Pui doar onSuccess și uiți de erori. Fără onFailure (sau o verificare), un eșec trece neobservat.

Comenzi înrudite

  • runCatching: Rulează un bloc și prinde orice excepție într-un Result; valoarea se scoate cu getOrNull, getOrElse sau getOrThrow.
  • Result.map: map transformă valoarea unui Result reușit și lasă eroarea neschimbată; fold dă o valoare finală din ambele cazuri.