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

Android Kotlin+Flow使用Apollo 3 GraphQL订阅网络异常优雅处理方案

问题根因

你遇到的java.lang.IllegalStateException: WebSocket queue full异常属于Apollo3 WebSocket引擎内部抛出的未托管异常,触发场景是开启飞行模式后WebSocket连接已失效,Apollo内部尝试发送停止订阅的控制帧时,WebSocket写入队列已满无法写入,该异常没有被传递到订阅返回的Flow消费链中,因此你在execute()返回的Flow后添加的catch操作符无法捕获。

解决方案

1. 配置WebSocket全局异常处理器(必选)

Apollo3的WebSocketNetworkTransport提供了专门的webSocketErrorHandler参数,所有WebSocket层抛出的异常都会回调到该处理器,你可以在这里捕获异常避免崩溃:

ApolloClient.Builder()
    .networkTransport(
        WebSocketNetworkTransport(
            serverUrl = baseUrl,
            webSocketErrorHandler = { throwable ->
                // 按需处理异常,不需要抛出即可避免应用崩溃
                if (throwable is IllegalStateException && throwable.message?.contains("WebSocket queue full") == true) {
                    // 可添加埋点日志上报这类异常,不影响业务运行
                }
                // 其他WebSocket异常也可在这里统一处理
            }
        )
    ).build()

2. 调大WebSocket队列容量(可选优化)

如果你的业务场景会短时间发送大量WebSocket帧,可以主动调大队列上限,默认队列大小为64,可根据业务需要调整:

// 自定义OkHttp WebSocket引擎,设置更大的队列容量
val customWsEngine = OkHttpWebSocketEngine(
    webSocketFactory = OkHttpClient().newWebSocketFactory(),
    maxQueueSize = 256
)
// 传入自定义引擎到WebSocket传输配置
WebSocketNetworkTransport(
    serverUrl = baseUrl,
    engine = customWsEngine,
    webSocketErrorHandler = { /* 异常处理逻辑 */ }
)

3. 主动监听网络状态管理订阅生命周期(可选优化)

在Android端注册网络状态监听,当检测到网络断开(如飞行模式开启)时,主动取消订阅Flow的收集任务,避免Apollo内部向已失效的连接写入控制帧:

// 示例:在ViewModel中使用生命周期作用域收集订阅
viewModelScope.launch {
    apolloClient.subscribe(ProfileSubscription()).execute()
        .catch { /* 这里可以捕获业务层的订阅异常 */ }
        .collect { subscriptionData ->
            // 处理订阅返回的更新数据
        }
}
// 网络断开时取消对应作用域,即可自动终止订阅,避免无效写入

4. 升级Apollo依赖版本(可选)

该类WebSocket未捕获异常的问题在Apollo 3.7.0及以上版本已经做了默认兼容处理,内部会自动捕获写入异常不会直接抛出导致崩溃,如果你的项目允许升级依赖,可以优先升级到最新稳定版解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:24:04