如何将Query Flow内的toDataClass解析错误传递到外部catch块?
解决思路及代码调整
问题核心在于:toDataClass的异常发生在Flow的map操作符内部,属于流的异步执行阶段,不在当前方法的同步try-catch覆盖范围内,所以外层catch无法捕获到这个异常。要实现需求,需要在流的处理链中捕获转换异常,并将其传递出去,同时保持返回值类型不变。
具体修改步骤:
- 将
mapNotNull替换为map,因为我们不再需要过滤null,而是要在转换失败时抛出异常。 - 在
toDataClass调用处添加局部try-catch,捕获转换异常并重新包装抛出,确保异常能流入流的处理链。 - 可选:在Flow链中添加
catch操作符,统一处理流中的所有异常,包括转换异常和查询异常。
修改后的代码示例:
try { val query = query goes here val queryFlow = query .queryChangeFlow() .map { queryChange -> val err = queryChange.error if (err != null) { throw err // 保留原有的查询错误抛出逻辑 } val data = queryChange.results?.allResults()?.map { result -> val cblDocument = result.getDictionary(0) try { // 捕获toDataClass的转换异常,若文档为null也抛出异常 cblDocument?.toDataClass<UserData>() ?: throw NullPointerException("Document dictionary is null") } catch (parseEx: Exception) { // 包装异常并重新抛出,让异常进入流的处理链 throw RuntimeException("Failed to parse document to UserData", parseEx) } } ?: emptyList() data } .catch { e -> // 统一记录流中出现的所有异常,然后重新抛出给上层 Log.e("MLG", "Flow processing error", e) throw e } .asLiveData() return queryFlow.asFlow() } catch (e: Exception) { Log.e("MLG", "Initialization error", e) throw e }
关键说明:
- 原外层
try-catch只能捕获Flow创建阶段的异常(比如query初始化错误),无法捕获流执行阶段的异常(比如文档转换错误)。 - 流中的异常会在Flow被收集(比如调用
collect方法)时触发,上层收集代码需要做好异常捕获,或者通过catch操作符在流内统一处理后传递。
内容的提问来源于stack exchange,提问作者Nie Selam
相关产品推荐
相关产品推荐

