在鸿蒙里优雅地处理网络错误:从 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 里处理。这样项目里的调用者就只需要关注业务逻辑。

总结

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

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

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

相关推荐
zhanshuo6 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw12 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw13 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw15 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw16 小时前
鸿蒙音频编码
harmonyos
whysqwhw16 小时前
鸿蒙音频解码
harmonyos
whysqwhw16 小时前
鸿蒙视频解码
harmonyos
whysqwhw16 小时前
鸿蒙视频编码
harmonyos
ajassi200016 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos