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
相关产品推荐
相关产品推荐

