鸿蒙端云一体的网络层设计:统一 HttpUtil、超时重试与错误码收敛

举报
yd_288537773 发表于 2026/11/10 08:44:18 2026/11/10
【摘要】 把鸿蒙端云一体的网络层收口到一个 HttpUtil:分层超时、只对可重试错误做指数退避重试、用统一 ApiResult 收敛错误码,附代码与实战细节。

鸿蒙端云一体的网络层设计:统一 HttpUtil、超时重试与错误码收敛

做端云一体的鸿蒙应用,最容易失控的不是 UI,也不是云函数,而是网络层。一开始每个页面自己写一份 http 请求,写着写着就会发现:超时时间不统一、错误处理五花八门、加个重试要改十几处。这篇把网络层的设计收敛成一条清晰的线:统一入口、统一超时与重试、统一错误码。

一、为什么必须收口到一个 HttpUtil

如果每个页面各自 @ohos.net.http,会出三个问题:

  1. 无法统一加超时、重试、日志;
  2. 错误码散落各处,排查要翻十个文件;
  3. 换后端地址或加签名字段时,改到崩溃。

所以第一件事:全应用只允许一个 HttpUtil 出口,其他模块一律调它。

二、超时:分两层

网络超时不是一个数能盖住的,至少要分两层:

  • 连接超时(connectTimeout):建立 TCP 连接的时间,设短一点,5 秒;
  • 读取超时(readTimeout):等响应体的时间,设长一点,15 秒。
const httpRequest = http.createHttp();
const res = await httpRequest.request(url, {
  method: http.RequestMethod.POST,
  header: { 'Content-Type': 'application/json' },
  extraData: JSON.stringify(body),
  connectTimeout: 5000,
  readTimeout: 15000
});

三、重试:只重试“可重试”的错误

不是所有失败都该重试。盲目重试会把一个 400 变成十次 400,甚至触发风控。经验规则:

  • 网络异常、连接超时、5xx:可重试,指数退避(1s、2s、4s),最多 3 次;
  • 4xx(除 429):不重试,直接报错;
  • 429 限流:退避后重试,且读取 Retry-After。
async function requestWithRetry(cfg, maxRetry = 3) {
  let lastErr;
  for (let i = 0; i <= maxRetry; i++) {
    try {
      const r = await doRequest(cfg);
      if (r.status >= 500 && i < maxRetry) throw new Error('server 5xx');
      return r;
    } catch (e) {
      lastErr = e;
      if (!isRetryable(e) || i === maxRetry) break;
      await sleep(1000 * Math.pow(2, i));
    }
  }
  throw lastErr;
}

注意:只有幂等请求(GET、带幂等键的写操作)才能安全重试。写操作重试前先确认服务端有幂等保护,否则可能重复下单。

四、错误码收敛:给上层一个“业务错误”

底层可能是 HTTP 状态码、也可能是业务 code,还可能是网络异常。上层不应该关心这些差异,网络层应该把它们统一成一种结构:

type ApiResult<T> = { ok: true; data: T } | { ok: false; code: string; msg: string };

规则:

  • 2xx 且业务 code 正常 → ok:true;
  • 4xx/5xx 或业务 code 异常 → ok:false,code 用业务错误码(如 AUTH_EXPIRED、RATE_LIMITED),msg 用可展示文案;
  • 网络异常 → ok:false,code=NETWORK_ERROR。

这样页面只写 if (!res.ok) 处理业务错误,不用再判断一堆 HTTP 状态码。

五、几个实战细节

  1. 统一加日志与 traceId:每次请求带一个 traceId,服务端回写,出问题一搜链路日志就能定位。
  2. 取消请求:页面退出时 abort 未完成的请求,避免回调打到一个已销毁的页面。
  3. 鉴权拦截:token 过期统一在 HttpUtil 里拦截 401,跳登录,不要让每个接口自己处理。
  4. 不要吞异常:catch 里至少 log,否则线上永远找不到问题。

小结

网络层设计的核心不是写多少代码,而是把变化收敛到一个地方:入口一个、超时重试一处、错误码一种。做到这三点,后面加接口、换后端、排查问题都会轻很多。端云一体的项目尤其如此——云侧会变,端侧网络层得稳。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。