Kotlin Academy · Lektion

Arrow-Raise-DSL: Typisierte Fehler kombinieren

Verwenden Sie den Raise-Kontext von Arrow und raise(), um Abläufe mit mehreren Fehlern übersichtlich zu kombinieren.

Lektion 2 von 413 Schritte

Arrow-Raise-DSL: Typisierte Fehler kombinieren ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Die Einschränkung der Either-Verkettung

Das Verketten von Either mit flatMap führt bei mehreren aufeinanderfolgenden Operationen zu tief verschachtelten Lambdas. Der Arrow-Raise DSL (eingeführt in Arrow 1.2) bietet mit einer Coroutine-ähnlichen Syntax eine übersichtlichere Alternative, die Kotlin-Context-Receiver oder Erweiterungsfunktionen verwendet.

Was ist Raise<E>?

Raise ist ein Kontext, der einen Fehler vom Typ E auslösen (und damit die Verarbeitung sofort abbrechen) kann. Eine fehleranfällige Funktion ruft raise(error) auf, um abzubrechen und den Fehler weiterzugeben — ähnlich wie beim Auslösen einer Exception, jedoch ohne Exceptions.

Der Builder either { }

Der Builder either { } erstellt ein Either aus einem Block, in dessen Gültigkeitsbereich ein Raise verfügbar ist. Darin verwenden Sie raise(error) für einen Fehler oder geben für einen Erfolg einfach einen Wert zurück:

import arrow.core.raise.either
import arrow.core.raise.Raise

fun validateAge(age: Int): Either<String, Int> = either {
    if (age < 0) raise("Age cannot be negative")
    if (age > 150) raise("Age too large")
    age
}

bind() — Either innerhalb von either{} entpacken

Rufen Sie innerhalb eines either { }-Blocks .bind() für jeden Either-Wert auf, um ihn zu entpacken. Ist der Wert ein Left, löst bind() automatisch einen Fehler aus und bricht den Block sofort ab:

fun createUser(name: String, age: Int): Either<String, User> = either {
    val validName = validateName(name).bind()  // raises if Left
    val validAge  = validateAge(age).bind()    // raises if Left
    User(validName, validAge)                  // only reached if both succeed
}

ensure() — Inline-Bedingungsprüfung

ensure(condition) { error } ist eine Kurzform für if (!condition) raise(error). Dadurch bleibt die Validierungslogik kompakt:

fun validateEmail(email: String): Either<String, String> = either {
    ensure(email.contains("@")) { "Email must contain @" }
    ensure(email.length <= 255) { "Email too long" }
    email
}

ensureNotNull() — Nullprüfung mit Raise

ensureNotNull(value) { error } entpackt einen nullable Wert oder löst einen Fehler aus, wenn er null ist:

fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
    ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}

Raise mit Context-Receivern (Arrow 1.2+)

Sie können Funktionen deklarieren, die direkt einen Raise-Kontext voraussetzen, ohne sie in either { } einzuschließen:

context(Raise<String>)
fun requirePositive(n: Int): Int {
    ensure(n > 0) { "Must be positive" }
    return n
}

// Called inside either { }
val result = either { requirePositive(-1) }  // Left("Must be positive")

Fehler mit zipOrAccumulate sammeln

Standardmäßig bricht Raise beim ersten Fehler ab. Verwenden Sie zipOrAccumulate(), um mehrere Validierungen auszuführen und alle Fehler in einer NonEmptyList zu sammeln:

val result: Either<NonEmptyList<String>, User> = either {
    zipOrAccumulate(
        { validateName(name).bind() },
        { validateAge(age).bind() }
    ) { validName, validAge -> User(validName, validAge) }
}

recover { } — Bestimmte Fehler behandeln

Verwenden Sie recover { error -> ... } innerhalb von either { }, um einen bestimmten ausgelösten Fehler zu behandeln, einen Ersatzwert bereitzustellen und die Berechnung fortzusetzen:

val name: String = either {
    findUser(0L).bind().name
}.recover { error ->
    if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"

Raise und Either-Verkettung: Wann Sie was verwenden sollten

Verwenden Sie either { }.bind() für lineare Abläufe mit mehreren aufeinanderfolgenden Schritten — der Code liest sich wie imperativer Code, bleibt aber rein. Verwenden Sie die flatMap-Verkettung für kurze Kompositionen aus zwei Schritten oder wenn Sie sie mit anderen funktionalen Bibliotheken kombinieren.

Raise-basierte Funktionen testen

Testen Sie, indem Sie die Funktion innerhalb von either { } aufrufen und das Ergebnis überprüfen. Die Kotest-Matcher shouldBeLeft() und shouldBeRight() von Arrow ermöglichen kompakte Assertions:

import arrow.core.shouldBeLeft
import arrow.core.shouldBeRight

@Test
fun `negative age returns Left`() {
    validateAge(-1).shouldBeLeft()
}

@Test
fun `valid age returns Right`() {
    validateAge(25).shouldBeRight(25)
}

Kurze Überprüfung

Was geschieht innerhalb eines either { }-Blocks, wenn Sie .bind() für einen Either.Left-Wert aufrufen?

Zusammenfassung: Arrow Raise DSL

Wichtige Erkenntnisse:

  • either { } erstellt ein Either aus einem Block, in dessen Gültigkeitsbereich Raise verfügbar ist
  • .bind() entpackt Either und bricht bei Left sofort ab
  • ensure(condition) { error } und ensureNotNull(value) { error } für Inline-Prüfungen
  • zipOrAccumulate(), um mehrere Fehler zu sammeln, anstatt beim ersten Fehler abzubrechen
  • Liest sich wie imperativer Code und bleibt dabei rein funktional
Kostenlos starten

Lerne Kotlin mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
51
Lektionen
203

Häufig gestellte Fragen

Ist die Lektion „Arrow-Raise-DSL: Typisierte Fehler kombinieren“ kostenlos?

Ja — der vollständige Text von „Arrow-Raise-DSL: Typisierte Fehler kombinieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Arrow-Raise-DSL: Typisierte Fehler kombinieren“?

Verwenden Sie den Raise-Kontext von Arrow und raise(), um Abläufe mit mehreren Fehlern übersichtlich zu kombinieren. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Arrow-Raise-DSL: Typisierte Fehler kombinieren“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Either : Typsichere Fehlerbehandlung ohne Exceptions
  2. Arrow-Raise-DSL: Typisierte Fehler kombinieren
  3. Option und Nullable: Wann Sie welches verwenden
  4. Funktionale Domänenmodellierung mit Arrows Core-Typen
← Zurück zu Kotlin Academy