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

HttpClientRequest设置timeout回调抛出未处理异常如何解决

问题描述

尝试给HttpClientRequest对应Future的timeout方法设置onTimeout回调,代码编译阶段无报错,运行时抛出未处理异常:

type '() => Future<HttpClientRequest>' is not a subtype of type '(() => FutureOr<_HttpClientRequest>)?' of 'onTimeout'

复现代码如下:

void main() async {
  requestify();
}

Future<HttpClientRequest> requestify() async {
  var client = HttpClient();
  var request = client.get('10.255.255.1', 80, '');
  // request.timeout(const Duration(seconds: 1));
  request.timeout(const Duration(seconds: 1), onTimeout: () {
    print('timed out');
    return request;
  });
  return request;
}
错误原因
  • 类型不匹配:client.get()方法返回的Future实际包装的是内部私有实现类_HttpClientRequest,不是公开的抽象类HttpClientRequest。timeout方法的onTimeout回调要求返回值类型必须和原Future的实际承载类型完全一致,你写的回调返回Future<HttpClientRequest>,和要求的FutureOr<_HttpClientRequest>类型不兼容,运行时做类型检查就会抛错。
  • 逻辑失效:timeout方法不会修改原Future对象,而是返回一个绑定了超时逻辑的新Future。你代码里调用request.timeout()后没有接收返回值,直接返回了原request,就算类型不报错,你写的超时回调也根本不会触发。
  • 逻辑错误:超时触发时原请求已经处于挂起等待状态,你在回调里直接返回原request对象没有任何实际意义,后续请求流程还是会卡住。
正确写法

常规场景下超时直接抛出指定异常即可,记得接收timeout返回的新Future:

import 'dart:async';
import 'dart:io';

void main() async {
  try {
    var req = await requestify();
    print('请求成功');
  } catch (e) {
    print('请求异常: $e');
  }
}

Future<HttpClientRequest> requestify() async {
  var client = HttpClient();
  // 必须用await接收timeout返回的新Future,超时逻辑才会生效
  var request = await client.get('10.255.255.1', 80, '').timeout(
    const Duration(seconds: 1),
    onTimeout: () {
      print('请求超时');
      client.close(); // 关闭挂起的客户端,避免资源泄漏
      throw TimeoutException('连接服务器超时,1秒内未得到响应');
    },
  );
  return request;
}

如果确实需要超时后返回默认请求对象,直接在回调里构造对应实例返回即可,Dart会自动完成类型适配,不要返回原挂起的request对象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:18:12