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

Dart中http.send抛出的Connection closed while receiving data异常如何捕获?

异常未捕获的核心原因
  • 同步try/catch无法捕获异步方法抛出的异常,_client.send(request)返回异步Future,其产生的异常不会进入同步捕获逻辑
  • response.catchError会返回一个新的处理过异常的Future,你没有持有和使用这个返回值,原Future的异常依旧会抛出
  • 你为response设置的onError回调里又把异常重新抛出,相当于没有处理异常
  • response.asStream().listen()未配置onError回调,数据流的错误会直接作为未处理异常抛出,就是你看到的报错来源
修复实现方案

你可以直接在stream的listen方法中添加onError回调捕获连接异常,同时添加重连逻辑,完整代码参考如下:

import 'dart:math';

// 定义全局控制参数,避免销毁后重复重连
bool _shouldReconnect = true;
int _retryCount = 0;
http.Client? _client;
StreamSubscription? _streamSubscription;

Future<void> connectSse(String url) async {
  try {
    // 每次连接前清理旧的资源
    _client?.close();
    await _streamSubscription?.cancel();
    
    _client = http.Client();
    var request = http.Request("GET", Uri.parse(url));
    request.headers["Cache-Control"] = "no-cache";
    request.headers["Accept"] = "text/event-stream";

    final response = await _client!.send(request);
    // 连接成功重置重试次数
    _retryCount = 0;
    
    _streamSubscription = response.stream.listen(
      (data) {
        // 原有服务端事件处理逻辑
      },
      onError: (e) {
        Log.e("连接出现异常: $e");
        _triggerReconnect(url);
      },
      onDone: () {
        Log.e("连接已断开");
        _triggerReconnect(url);
      },
      cancelOnError: false, // 错误时不自动取消订阅,方便自行控制重连逻辑
    );
  } catch (e) {
    Log.e("建立连接失败: $e");
    _triggerReconnect(url);
  }
}

void _triggerReconnect(String url) {
  if (!_shouldReconnect) return;
  // 重试间隔递增,最多间隔30秒,避免频繁请求压垮服务端
  final delay = Duration(seconds: min(_retryCount * 2, 30));
  _retryCount++;
  Future.delayed(delay, () => connectSse(url));
}

// 页面销毁/主动断开连接时调用,避免不必要的重连
void disposeSse() {
  _shouldReconnect = false;
  _client?.close();
  _streamSubscription?.cancel();
}
注意事项
  • 主动断开连接时要把_shouldReconnect置为false,避免不需要重连的场景下反复发起请求
  • 每次重连前必须关闭旧的http client和订阅,避免资源泄漏
  • 可以根据业务需求调整重试间隔的上限和递增规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:06:07