Co wiesz o obsłudze błędów w Flow?
sobes.tech AI
Odpowiedź od AI
Flow w Kotlin Coroutines oferuje kilka sposobów obsługi błędów:
-
Operator
catch: Przechwytuje wyjątki w strumieniu wznoszącym i pozwala wykonać akcję (np. logowanie, zwrócenie danych zapasowych) lub zastąpić strumień.flow { emit(1) throw RuntimeException("Wystąpił błąd") }.catch { e: Throwable -> // Obsługa błędu emit(-1) // Emituj inną wartość w przypadku błędu }.collect { value -> // Obsługa wartości } -
Blok
try-catch: Klasyczny sposób obsługi wyjątków wokół fragmentu kodu, w tym zbierania Flow.try { flow { emit(1) throw RuntimeException("Wystąpił błąd") }.collect { value -> // Obsługa wartości } } catch (e: Throwable) { // Obsługa błędu }Ten sposób przechwytuje błędy występujące podczas zbierania Flow, ale nie błędy generowane przez emitera Flow przed zbieraniem.
-
Operator
onEachztry-catch: Jeśli chcesz obsłużyć błędy dla każdego elementu osobno.flow { emit(1) emit(2) throw RuntimeException("Błąd po 2") emit(3) }.onEach { value -> try { // Obsługa każdego elementu if (value == 2) throw IllegalArgumentException("Nieprawidłowa wartość 2") } catch (e: Throwable) { // Obsługa błędu dla konkretnej wartości println("Błąd dla wartości $value: ${e.message}") // Można rzucić wyjątek dalej, aby zatrzymać strumień throw e } }.catch { e: Throwable -> // Obsługa błędów nieprzechwyconych w onEach lub błędów rzuconych po onEach println("Ostateczny błąd: ${e.message}") }.collect { value -> println("Zebrana wartość: $value") } -
Operator
retry/retryWhen: Pozwalają powtórzyć próbę źródła Flow w przypadku błędu.retry: Po prostu powtarza próbę określoną liczbę razy.retryWhen: Pozwala zdefiniować warunek powtórzenia.
var attempt = 0 flow { println("Próba ${++attempt}") if (attempt < 3) throw RuntimeException("Powtórka") emit(10) }.retryWhen { cause, attempt -> // Logika określenia, czy powtórzyć cause is RuntimeException && attempt < 3 }.collect { value -> println("Sukces: $value") } -
Propagacja wyjątków: Błędy nieprzechwycone jawnie będą propagowane w górę łańcucha Flow i mogą być przechwycone w bloku
try-catchwokół zbieracza Flow lub operatoremcatch.
Ważne jest, aby zrozumieć, że operator catch przechwytuje błędy w strumieniu wznoszącym (upstream). Błędy pojawiające się w strumieniu opadającym (downstream) po catch nie są przechwytywane. Aby obsłużyć takie błędy, należy użyć innego catch poniżej w łańcuchu lub try-catch wokół zbieracza.
Ogólna rekomendacja: umieścić obsługę błędów tak blisko źródła błędu, jak to możliwe, ale pamiętać, że catch obsługuje tylko strumień wznoszący.