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

Flutter中如何正确捕获网络及各类错误?

解决Flutter/Dart错误处理困惑:如何知晓SDK抛出的异常及规范

一、官方文档与SDK异常查询方法

1. Dart内置函数异常

Dart核心库的多数函数会在API文档的Throws部分明确标注抛出的异常类型,比如http包的Client.post会说明可能抛出ClientException。部分底层函数依赖平台实现,文档会提示可能存在平台相关异常。

2. Firebase SDK异常

Firebase Flutter SDK有明确的异常分层:

  • FirebaseException:绝大多数Firebase操作会抛出此类异常,其code字段对应官方定义的错误码(比如Remote Config的internal、remote-config-server-error),Firebase官方文档会按模块列出每个方法的错误码及含义,网络类错误可通过错误码归类处理。
  • PlatformException:当SDK调用原生平台代码时触发,这类异常的code和message对应原生SDK的定义(比如Android端的SERVICE_UNAVAILABLE会映射为Flutter端的PlatformException消息),可参考Firebase的Android/iOS原生文档获取完整异常列表。

3. 第三方包异常

  • 查看包的pub.dev页面或GitHub仓库的README、文档板块,维护良好的包会在方法注释中标注抛出的异常类型;
  • 直接查看包的源码,搜索throw关键字,定位所有抛出的异常类型及触发条件。

二、高效异常处理实践技巧

1. 统一异常封装

针对网络错误这类通用场景,封装自定义异常(如你使用的NetworkUnavailableError),在全局或业务层统一捕获不同SDK的异常并转换,避免重复的字符串匹配逻辑:

// 全局网络异常处理工具
Future<T> handleNetworkException<T>(Future<T> Function() action) async {
  try {
    return await action();
  } on FirebaseException catch (e) {
    if (_isFirebaseNetworkError(e)) {
      throw NetworkUnavailableError(null, e);
    }
    rethrow;
  } on PlatformException catch (e) {
    if (_isPlatformNetworkError(e)) {
      throw NetworkUnavailableError(null, e);
    }
    rethrow;
  } on http.ClientException catch (e) {
    if (e.message.contains("Failed host lookup")) {
      throw NetworkUnavailableError("Can't reach servers.", e);
    }
    rethrow;
  }
}

// 判断Firebase网络错误的辅助方法
bool _isFirebaseNetworkError(FirebaseException e) {
  const networkCodes = {"internal", "remote-config-server-error", "unknown"};
  if (!networkCodes.contains(e.code)) return false;
  return e.code != "unknown" || (e.message?.contains("SERVICE_NOT_AVAILABLE") ?? false);
}

// 判断Platform网络错误的辅助方法
bool _isPlatformNetworkError(PlatformException e) {
  const networkTriggers = {
    "network_error",
    "The server is unavailable",
    "Unable to connect to the server",
    "Unable to resolve host"
  };
  return e.code == "network_error" || networkTriggers.any((t) => e.toString().contains(t));
}

2. 提前测试异常场景

通过单元测试或集成测试模拟异常:用Mockito模拟Firebase返回特定错误码,或用网络拦截工具模拟断网,提前覆盖所有可能的异常类型,无需依赖生产环境的Crash报告。

3. 利用IDE提示

在Android Studio/VS Code中,按住Ctrl点击方法名查看源码注释,部分方法会通过@throws标签说明抛出的异常类型及场景。

三、现有规范说明

Dart采用非检查型异常设计(无Java式throws强制声明),但官方SDK和优质第三方包普遍遵循以下规范:

  • 优先使用特定异常类型而非通用Exception;
  • 异常携带明确的错误码或可读消息,便于识别;
  • 核心方法的异常会在官方文档中说明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:48:12