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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 16:12:28