HoRain云--Dart异常处理全攻略:从入门到精通
HoRain云小助手个人主页 个人专栏: 《Linux 系列教程》《c语言教程》⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。专栏介绍专栏名称专栏介绍《C语言》本专栏主要撰写C干货内容和编程技巧让大家从底层了解C把更多的知识由抽象到简单通俗易懂。《网络协议》本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘一起解密网络协议在运行中协议的基本运行机制《docker容器精解篇》全面深入解析 docker 容器从基础到进阶涵盖原理、操作、实践案例助您精通 docker。《linux系列》本专栏主要撰写Linux干货内容从基础到进阶知识由抽象到简单通俗易懂帮你从新手小白到扫地僧。《python 系列》本专栏着重撰写Python相关的干货内容与编程技巧助力大家从底层去认识Python将更多复杂的知识由抽象转化为简单易懂的内容。《试题库》本专栏主要是发布一些考试和练习题库涵盖软考、HCIE、HRCE、CCNA等目录⛳️ 推荐专栏介绍抛出与捕获基础多个 catch 子句自上而下匹配finally无论成败都执行rethrow保留原始堆栈的再抛出自定义异常与 Error 的区分异步代码中的异常处理Dart 2.16 推荐Error.throwWithStackTrace一个完整的处理范式Dart 的异常处理围绕throw—try—catch—finally​ 这套结构化机制展开。Dart 中任何非 null 对象都可以被抛出——不仅限于ExceptionError乃至普通对象都能 throwthrow本身是个表达式所以可以直接写在函数体里void distanceTo(Point other) throw UnimplementedError();。下面按抛出 → 捕获 → 清理 → 重抛/包装的顺序过一遍。抛出与捕获基础try { breedMoreLlamas(); } on OutOfLlamasException { // 只关心类型不需要异常对象 buyMoreLlamas(); }on和catch可以单独用也可以组合只用on Type只想针对某类异常做处理不需要拿到异常对象只用catch (e)需要异常对象但不关心类型on Type catch (e, s)既要类型匹配又要异常对象和堆栈catch的第二个参数s是StackTrace对象排查线上问题非常关键。多个 catch 子句自上而下匹配Dart 允许多个on/catch子句第一个匹配到类型的子句生效后续忽略。所以具体类型要写在前面宽泛的写在后面try { breedMoreLlamas(); } on OutOfLlamasException { // 特定异常优先处理 buyMoreLlamas(); } on Exception catch (e) { // 其他 Exception print(Unknown exception: $e); } catch (e) { // 没有指定类型 兜底能捕获一切包括 Error print(Something really unknown: $e); }⚠️ 兜底catch (e)会连Error一起吞掉。Effective Dart 明确建议大多数情况下应该捕获Exception而不是所有类型Exception是所有运行时异常的基类它排除了代表代码 bug 的Error。finally无论成败都执行资源清理、状态复位等必须跑的逻辑放在finallytry { breedMoreLlamas(); } catch (e) { print(Error: $e); // 先处理异常 } finally { cleanLlamaStalls(); // 再清理 }如果try中没有catch匹配到异常finally执行完后异常会继续向上传播。rethrow保留原始堆栈的再抛出这是 Dart 异常处理里最容易被误用的一点。看两段代码的区别// ❌ 错误示范throw e 会重置堆栈到当前位置 try { somethingRisky(); } catch (e) { if (!canHandle(e)) throw e; // 堆栈从这里重新开始 handle(e); } // ✅ 正确做法rethrow 保留原始堆栈 try { somethingRisky(); } catch (e) { if (!canHandle(e)) rethrow; // 堆栈信息完整保留 handle(e); }rethrow只能在catch块内使用它会把异常原封不动含原始堆栈继续向上抛。Effective Dart 专门有一条 lint 规则use_rethrow_when_possible来强制这一点。自定义异常与 Error 的区分Dart 里有两个重要的基类语义不同类型用途示例Exception运行时失败不代表代码 bug​FormatException、IOExceptionError程序错误意味着代码有 bugArgumentError、StateError、OutOfMemoryError指导原则你的 API 想报告调用方用错了 → 抛Error子类如ArgumentError运行时失败、不代表 bug → 抛Exception或其子类不要​catch具体的Error类型lint 规则avoid_catching_errors因为Error应该一路冒泡直到终止程序并打印堆栈让你定位修复 bug捕获它会掩盖问题自定义异常很简单实现Exception接口即可class OutOfLlamasException implements Exception { final String message; OutOfLlamasException(this.message); override String toString() OutOfLlamasException: $message; }异步代码中的异常处理try-catch在async函数中对同步和异步代码同样有效直接await可能抛出的异步操作即可Future describeFlybyObjects(List flybyObjects) async { try { for (final object in flybyObjects) { var description await File($object.txt).readAsString(); print(description); } } on IOException catch (e) { print(Could not describe object: $e); } finally { flybyObjects.clear(); } }如果是即发即弃的Future且你确实不在乎成功与否可以调用.ignore()FirebaseAnalytics.instance.logAppOpen().ignore();Dart 2.16 推荐Error.throwWithStackTrace有时候你需要在catch块里抛出一个新的异常比如把底层异常包装成业务异常但又不想丢失原始堆栈。这时候直接用throw NewException()会丢失原堆栈——Dart 2.16 引入的Error.throwWithStackTrace就是为解决这个问题try { final json await client.get(id); return Item.fromJson(json); } on Object catch (_, stackTrace) { Error.throwWithStackTrace( ApiException(Something goes wrong), stackTrace, ); }它的作用是带着原始的stackTrace​ 抛出新的错误。如果error继承自Error且之前未被抛出过其Error.stackTrace属性会被设为传入的stackTrace。相应的DCM 等静态分析工具提供了avoid_throw_in_catch_block规则专门警告在 catch 块内直接throw会丢失原堆栈的反模式。 简单记想原样继续抛 →rethrow想换成新异常但保留原堆栈 →Error.throwWithStackTrace。一个完整的处理范式综合上面所有要点这是 Dart 中处理异常的标准范式FutureItem fetchItem(String id) async { try { final json await client.get(id); return Item.fromJson(json); } on FormatException { // 可预见的、可恢复的异常 → 返回默认值或特殊标记 return const Item.empty(); } on TimeoutException catch (e, s) { // 可预见但需要包装的异常 → 保留堆栈 Error.throwWithStackTrace(ApiException(请求超时), s); } catch (e, s) { // 兜底记录日志后继续向上抛绝不静默吞掉 log.error(fetchItem failed: $e, stackTrace: s); rethrow; } finally { client.close(); } }几个必须遵守的实践准则绝不静默丢弃异常——on Object { return null; }是最糟糕的写法丢失堆栈后在 Crashlytics/Sentry 里几乎无法定位问题优先捕获具体类型不要用裸catch (e)一把梭不要捕获具体的Error子类让 bug 类错误自然冒泡重新抛出用rethrow包装异常用Error.throwWithStackTrace全局异步异常可以用runZonedGuarded兜住runZonedGuarded(() async { longAsyncOperation(); runApp(App()); }, (error, stackTrace) /* 上报 */);异常处理看似简单但在 Dart 里堆栈信息的保留是核心痛点——throw和rethrow一字之差线上排查难度天差地别。把rethrow和Error.throwWithStackTrace这两个工具用熟你的错误处理就达到了 Dart 社区的生产级标准。需要我再展开讲讲Future与Stream的异常处理差异还是Result类型函数式错误处理的替代方案❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧

相关新闻

STM32硬件SPI驱动三线SPI-LCD:协议解析与DMA优化实践

STM32硬件SPI驱动三线SPI-LCD:协议解析与DMA优化实践

1. 从三线SPI-LCD的“非主流”说起如果你玩过STM32驱动LCD,大概率用过8080并口或者标准的4线SPI。前者速度快但占引脚多,后者协议简单但也要4根线(SCK, MOSI, MISO, CS)。但最近在一些追求极致成本或特定封装的小尺寸LCD模块上&am…

2026/10/25 19:38:48 阅读更多 →
基于启发式搜索的最优路径规划算法研究7

基于启发式搜索的最优路径规划算法研究7

引言路径规划问题的背景与重要性启发式搜索在路径规划中的核心作用研究目标与文章结构概述路径规划问题定义路径规划的数学建模(图论与状态空间表示)最优路径的评估标准(如最短距离、最少时间、最低成本)常见应用场景(…

2026/10/24 20:06:46 阅读更多 →
Python在芯片健康评估中的实战应用

Python在芯片健康评估中的实战应用

1. 芯片健康评估:为什么需要Python这把"手术刀"在半导体行业摸爬滚打十几年,我见过太多工程师面对芯片异常时的手足无措。去年有个典型案例:某工业控制器批量出现间歇性死机,厂商更换了所有外围元件仍无法解决&#xff…

2026/10/25 23:38:30 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →