You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin Flow的catch块中发射Error状态?类型不匹配问题

Kotlin Flow中Catch块无法发射Error状态的原因与解决方法

问题原因

你的代码中第二个map操作会将Flow的类型从Flow<List<Review>>推断为Flow<State.Success<List<Review>>>——因为map的返回值是明确的State.Success实例。而State.Error属于State<Nothing>类型,虽然State<Nothing>是State<List<Review>>的协变子类,但当前Flow的泛型已经被限定为更具体的State.Success<List<Review>>,并非父类型State<List<Review>>,因此在catch块中发射State.Error会触发类型不匹配错误。

解决方法

方法一:显式指定Map操作的返回类型

通过显式声明map的返回类型为State<List<Review>>,让Flow的泛型保持为父类型,从而兼容State.Error的发射:

suspend fun getReviews(movieId: Long): Flow<State<List<Review>>> = withContext(IO) {
    flow { emit(api.getReviews(movieId)) }
        .map { it.sortedWith { item, _ -> if (item.userId == pref.getUserId()) -1 else 0 } }
        .map<_, State<List<Review>>> { State.Success(it) }
        .catch { error -> 
            emit(State.Error(error))
            Timber.e(error)
        }
}

方法二:使用Transform替代Map

transform操作符支持发射任意符合泛型的元素,比map更灵活,能直接在其中发射State.Success,同时让Flow保持State<List<Review>>的泛型:

suspend fun getReviews(movieId: Long): Flow<State<List<Review>>> = withContext(IO) {
    flow { emit(api.getReviews(movieId)) }
        .map { it.sortedWith { item, _ -> if (item.userId == pref.getUserId()) -1 else 0 } }
        .transform { data ->
            emit(State.Success(data))
        }
        .catch { error -> 
            emit(State.Error(error))
            Timber.e(error)
        }
}

方法三:用Flow构建器包裹完整逻辑

将所有逻辑放在flow构建器内部,更直观地控制状态发射,同时自然兼容异常处理:

suspend fun getReviews(movieId: Long): Flow<State<List<Review>>> = withContext(IO) {
    flow {
        // 可选:发射加载状态
        emit(State.Loading())
        val sortedReviews = api.getReviews(movieId)
            .sortedWith { item, _ -> if (item.userId == pref.getUserId()) -1 else 0 }
        emit(State.Success(sortedReviews))
    }.catch { error ->
        emit(State.Error(error))
        Timber.e(error)
    }
}

内容的提问来源于stack exchange,提问作者Samuel Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 13:45:30