Напишите функцию расширения для потока.поймайте

#kotlin #kotlin-coroutines #kotlin-flow

Вопрос:

Я хотел бы изменить функцию Flow.catch по умолчанию и всегда вызывать определенную функцию приостановки logOutIfUserHasNoAccount() . Моя текущая реализация:

 private suspend fun <T> Flow<T>.catchLoginError(action: suspend FlowCollector<T>.(Throwable) -> Unit): Flow<T> {
    logOutIfUserHasNoAccount()
    return catch(action)
}
 

Мои вопросы: Есть ли какой-либо недостаток в том, что моя функция Flow.catchLoginError также является функцией приостановки? Реализация catch по умолчанию является:

 // Not suspending
public fun <T> Flow<T>.catch(action: suspend FlowCollector<T>.(Throwable) -> Unit): Flow<T> { /* compiled code */ }
 

С помощью

 suspend fun login() = flow {

}.catchLoginError( e -> 
 // here it should call "logOufIfUserHasNoAccount" first
 doStuff(e) 
 

}

Комментарии:

1. Вы хотите выйти из системы только в случае ошибки? Как есть, ваша функция всегда будет выходить из системы до того, как начнется сбор потока.

2. В таком случае моя функция неверна. Я хочу выйти из системы только в том случае, если произошла ошибка!

Ответ №1:

Ваша функция при вызове немедленно вызывает функцию выхода из системы, а затем возвращает обернутую версию исходного потока, которая будет ловить ошибки при сборе.

Чтобы выходить из системы только при возникновении ошибок, вы должны переместить вызов внутри блока catch вызова. Это также не обязательно должна быть функция приостановки.

 fun <T> Flow<T>.catchLoginError(action: suspend FlowCollector<T>.(Throwable) -> Unit): Flow<T> = catch { error ->
    logOutIfUserHasNoAccount()
    action(error)
}