在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例

摘要

在做鸿蒙(HarmonyOS)应用开发时,网络请求基本是跑不掉的。无论是加载首页数据、拉取列表,还是提交表单,背后都依赖 HTTP 请求。可一旦遇到断网、超时、服务端 500 错误,应用就可能直接崩溃,用户体验会非常糟糕。

所以,如何优雅地处理网络错误,保证用户看到的不是"白屏"而是合理的提示,是开发过程中必须考虑的事情。

引言

随着鸿蒙生态越来越完善,应用也越来越复杂。以前我们可能只需要在局域网里访问接口,现在很多场景都涉及到公网请求,这也就意味着网络的不确定性大大增加。

比如:

  • 用户在地铁里,信号忽强忽弱;
  • 服务端升级中,短时间返回 503;
  • 网络延迟过大,导致超时;

这些问题都会在真实应用里遇到,所以处理网络错误并不仅仅是"加一个 try-catch",而是需要一个完整的容错方案。下面我会结合实际场景,展示具体的代码和解决办法。

鸿蒙里怎么捕获网络错误

最基本的做法就是在发起请求时对错误进行捕获和处理。鸿蒙提供了 @ohos.net.http 模块,可以很方便地发起请求并拿到结果。

基本 Demo

下面给一个最小可运行的示例:

ts 复制代码
import http from '@ohos.net.http';

@Entry
@Component
struct NetworkErrorDemo {
  @State message: string = '点击按钮请求数据';

  doRequest() {
    let httpRequest = http.createHttp();

    httpRequest.request(
      "https://example.com/api/data",
      {
        method: http.RequestMethod.GET,
        connectTimeout: 5000, // 超时时间
        readTimeout: 5000,
      },
      (err, data) => {
        if (err) {
          // 网络层异常,比如断网、超时
          this.message = `网络错误: ${err.message}`;
          return;
        }
        if (data.responseCode !== 200) {
          // 业务层异常,比如 404/500
          this.message = `请求失败: ${data.responseCode}`;
        } else {
          // 成功返回
          this.message = `成功: ${data.result}`;
        }
      }
    );
  }

  build() {
    Column() {
      Text(this.message)
        .fontSize(18)
        .margin(10)
      Button("发起请求")
        .onClick(() => this.doRequest())
        .margin(10)
    }
  }
}

这里的处理逻辑非常直接:

  • err 代表网络层的错误(比如超时、断网)。
  • data.responseCode 可以拿到 HTTP 状态码(比如 404、500)。
  • 成功的情况再去解析 data.result

这样就能避免"用户点了按钮→没反应→程序崩了"的情况。

统一错误处理工具函数

实际项目里,我们不可能每个请求都写一堆 if (err) { ... }。为了简化,可以写一个 统一的错误处理函数

ts 复制代码
function handleHttpError(err?: Error, data?: http.HttpResponse): string {
  if (err) {
    return `网络异常: ${err.message}`;
  }
  if (!data) {
    return '未知错误';
  }
  if (data.responseCode >= 500) {
    return `服务器异常: ${data.responseCode}`;
  }
  if (data.responseCode >= 400) {
    return `请求错误: ${data.responseCode}`;
  }
  return '';
}

在业务代码里,就能这样写:

ts 复制代码
httpRequest.request("https://example.com/api/data", {}, (err, data) => {
  const errorMsg = handleHttpError(err, data);
  if (errorMsg) {
    this.message = errorMsg;
    return;
  }
  this.message = `成功: ${data?.result}`;
});

这样做的好处是,错误处理逻辑都收敛在一个地方,后期维护和扩展会方便很多。

实际场景案例

登录接口失败重试

用户点登录按钮时,如果网络瞬时断开,可以提示用户"重试"。

ts 复制代码
async function login(username: string, password: string): Promise<string> {
  return new Promise((resolve, reject) => {
    let httpRequest = http.createHttp();
    httpRequest.request(
      "https://example.com/api/login",
      {
        method: http.RequestMethod.POST,
        extraData: { username, password }
      },
      (err, data) => {
        const errorMsg = handleHttpError(err, data);
        if (errorMsg) {
          reject(errorMsg);
          return;
        }
        resolve(data?.result ?? '');
      }
    );
  });
}

在 UI 层就可以:

ts 复制代码
Button("登录").onClick(async () => {
  try {
    let result = await login("test", "123456");
    this.message = `登录成功: ${result}`;
  } catch (error) {
    this.message = `登录失败: ${error}`;
  }
});

列表加载失败时的兜底

当首页列表请求失败,可以展示一个"重试按钮",而不是让用户看见空白。

ts 复制代码
if (this.message.startsWith("请求失败") || this.message.startsWith("网络错误")) {
  Button("重试")
    .onClick(() => this.doRequest())
}

异常埋点上报

很多团队会在网络异常时,把错误日志上报到服务器,用于后续分析。比如:

ts 复制代码
function reportError(error: string) {
  console.log("上报错误:", error);
  // 实际中可以发送到日志服务
}

调用时:

ts 复制代码
const errorMsg = handleHttpError(err, data);
if (errorMsg) {
  reportError(errorMsg);
  this.message = errorMsg;
  return;
}

这样就能知道"哪些用户经常遇到 500","是不是某个版本里断网频繁"等问题。

常见问题 QA

Q1:网络请求要不要统一加超时?

建议加。因为如果不加超时,用户可能卡死在加载中,体验会非常差。

Q2:不同的接口要不要写不同的错误处理逻辑?

可以通用处理大部分错误(比如断网、500),但关键业务(比如支付、登录)最好再做特殊处理。

Q3:能不能全局捕获所有网络错误?

可以。思路是对 http.request 再封装一层,把错误统一在 Promise.catch 里处理。这样项目里的调用者就只需要关注业务逻辑。

总结

网络错误处理在鸿蒙应用开发里是绕不开的话题。一个健壮的应用,不能只考虑"正常返回",还要考虑"异常兜底"。

通过:

  • 基础的错误捕获;
  • 统一的错误处理函数;
  • 结合实际业务场景(登录、重试、埋点);

我们就能构建一个既稳定又易维护的网络层,保证应用在各种网络环境下都能"有话可说",而不是让用户看到一个冷冰冰的白屏。

相关推荐
奶糖不太甜26 分钟前
鸿蒙图片资源加载全攻略:从基础到性能优化
harmonyos·图片资源
小小小小小星31 分钟前
鸿蒙多端适配开发指南:从入门到实战
harmonyos
鸿蒙小灰44 分钟前
鸿蒙开发之仿抖音APP教程:方法论与技术探索
harmonyos
CC__xy1 小时前
04 类型别名type + 检测数据类型(typeof+instanceof) + 空安全+剩余和展开(运算符 ...)简单类型和复杂类型 + 模块化
开发语言·javascript·harmonyos·鸿蒙
鸿蒙先行者1 小时前
鸿蒙开发ArkUI框架布局与适配难题丛生之响应式布局实现艰难
harmonyos·arkui
ajassi20002 小时前
开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载
华为·开源·harmonyos
changsanjiang2 小时前
鸿蒙 音视频边播放边缓存
harmonyos
墨雨听阁2 小时前
8.18网络编程——基于UDP的TFTP文件传输客户端
网络·网络协议·学习·udp
小晶晶京京2 小时前
day35-负载均衡
运维·网络·网络协议·学习·负载均衡