Android集成PowerSync启动报错:get()查询无返回行,求处理方案
问题分析与解决方案
PowerSync的get()方法设计逻辑是预期必须返回且仅返回1条数据,当查询结果为空(比如你当前空数据库的情况)或者返回多条数据时,都会抛出PowerSyncException,这就是你遇到报错的核心原因。
针对这种可能返回空结果的场景,你可以通过以下两种方式处理:
方案一:改用query()方法替代get()
query()方法支持返回0条、1条或多条结果,完全适配不确定是否存在数据的查询场景。修改代码如下:
fun selectGoalById(id: UUID): Flow<Goal?> { return flow { val goals = dataSource.getDatabase().query( sql = "SELECT * FROM goals WHERE id = ?", parameters = listOf(id) ) { cursor -> Goal( id = UUID.fromString(cursor.getString("id")), createdAt = cursor.getString("created_at"), userId = UUID.fromString(cursor.getString("user_id")), title = cursor.getString("title"), priority = cursor.getString("priority").toInt() ) } // 取第一条结果,无匹配数据则返回null emit(goals.firstOrNull()) } }
这种方式下,空库或无匹配ID时不会抛出异常,只会返回null,符合业务场景的容错需求。
方案二:保留get()但针对性捕获异常
如果坚持使用get(),可以在catch块中精准捕获无返回行的异常并处理,同时避免隐藏其他异常:
fun selectGoalById(id: UUID): Flow<Goal?> { return flow { try { val goal = dataSource.getDatabase().get( sql = "SELECT * FROM goals WHERE id = ?", parameters = listOf(id) ) { cursor -> Goal( id = UUID.fromString(cursor.getString("id")), createdAt = cursor.getString("created_at"), userId = UUID.fromString(cursor.getString("user_id")), title = cursor.getString("title"), priority = cursor.getString("priority").toInt() ) } emit(goal) } catch (e: PowerSyncException) { // 判断是否为无返回行的异常 if (e.message?.contains("returned no rows") == true) { emit(null) } else { // 重新抛出其他PowerSync异常,避免隐藏问题 throw e } } catch (e: Exception) { // 处理其他通用异常 throw e } } }
注意:原代码的空catch块会隐藏所有异常,调试时无法排查问题,务必避免这种写法。
额外提示
- 启动应用时如果数据库为空,建议先做初始化判断,避免执行依赖现有数据的
get()查询。 - 业务场景明确有且仅有1条数据时用
get(),不确定数据是否存在时优先用query()。
内容的提问来源于stack exchange,提问作者Joyce Opio
相关产品推荐
相关产品推荐

