更精准更简洁: Flutter 改进错误信息提示
On Compiler Error Messages: What They Say and What They Mean
https://www.hindawi.com/journals/ahci/2010/602570/abs/
引入结构化报错信息
在最新版 IntelliJ / Android Studio 的 Flutter 插件和 VS Code 的 Flutter 扩展中,我们发布了一个新功能。这项功能能够以丰富而简洁的格式显示报错信息。日志记录控制台现在可以显示具备以下几项改进的报错信息:
用红色突出显示报错信息摘要
在节段之间添加空白,让信息更易于浏览
如果报错信息包含解决错误的提示,用高亮文字来让它们更突出
折叠信息中的长列表和树状图
我们如何做到这些改进
上文中提到的 StackOverflow 问题 https://stackoverflow.com/questions/43947552/using-textfield-throws-no-material-widget-found-error
呈现报错信息的新方法
StackOverflow 上的这个问题很有启发性。它表明,报错信息中的各种信息所占的权重是不同的。这个问题也激发了我们的思考,如何才能使有用的信息更加显眼,这意味着我们需要减少视觉中的干扰。通过应用相关的视觉感知理论和 UX设计技巧,我们为该报错信息提出了三种改进的设计方案: 颜色、分段和省略。
视觉感知理论
https://www.interaction-design.org/literature/article/laws-of-proximity-uniform-connectedness-and-continuation-gestalt-principles-2
UX 设计技巧
https://www.nngroup.com/articles/progressive-disclosure
为了创建 “颜色” 这个方案,我们分析了报错信息中不同种类信息的相对重要性,并提出了一种简单的配色方案:
以红色显示报错的单行摘要
以蓝色显示与报错关联的对象
以灰色显示通常无需了解的细节
△ 改进方案 - 颜色
下一个方案是 “分段”。我们在报错信息中添加了空行,将其分成段落。我们还添加了诸如 “说明 (Explanation)” 和 “潜在修复方法 (Potential Fix)” 之类的段落标题,以使信息更易于浏览。
△ 改进方案 – 分段
最后,“省略” 这个方案在呈现报错信息时采用渐进式披露这个设计技巧,并活用了现代 IDE 的功能。例如,我们在显示 TextField widget 的参数列表和 widget 的祖先列表时,只显示前三个,然后就使用省略号 (…) 进行折叠。要查看列表的完整内容,只需单击省略号即可。这样生成的报错信息比原始信息短得多,让开发者可以更容易地关注信息中的更高级别元素。
渐进式披露 https://www.nngroup.com/articles/progressive-disclosure/
我们有充分的理由相信这些方案可以帮助开发者,但我们不确定能否证明为实现它们而付出的成本是否合理。为了实现上述这些设计方案,我们需要让 Flutter 框架将结构化的报错数据发送到 IDE,这样 IDE 才能针对不同部分进行布局 (例如摘要、细节和提示),并折叠不太重要的信息。我们需要回答这样一个问题: 对于开发者体验的潜在改进是否足以让我们重构 Flutter 的报错 API,以及用这个新的 API 重构现有的数百条报错信息。因此,我们决定进行一项实验,以了解实现结构化报错信息的 “性价比”。
实验
为了比较三种方案与原始报错信息的可用性差别,我们使用基于情景的问卷进行了在线实验。我们招募了 52 名 Flutter 开发者,他们被随机分配到四个实验组中的一个。我们把原始报错信息显示给对照组,把变体分别显示给三个试验组。在非常有限的时间内,我们要求被试描述报错信息的大意,以及如何修复这个错误。您可以在今年早些时候我们发表在 CHI 2019 的同行评审论文中找到详细的研究设计。
CHI 2019 研究论文
https://w.url.cn/s/AbfbDSg
这次实验的结果让我们惊喜。三个实验组的被试对报错信息的理解准确度都明显强过对照组。换句话说,无论使用哪种方案,在有限时间内正确理解报错信息的参与者的比例都要大大高于原始对照组。下图显示,当参与者需要在 45 秒内读取报错信息时,分段变体的性能优于原始格式约 38 个百分点。
同样,在确定解决方案时,报错信息的所有实验方案都优于原始格式。
△ 三种方案的报错信息解决准确度都明显高于原始格式
“右边的报错消息 (指 ‘颜色’ 方案) 改进很明显,关键的短信息以红色显示,受影响的 widget 则以蓝色显示。”
“隐藏整个 widget 对象 (指 ‘省略’ 方案) 可以减少干扰,我因此可以轻松找到报错发生的原因。”
“B 方案 (指 ‘分段’ 方案) 更容易理解。这些分段非常明晰,我在快速浏览时很容易知道下一步要跳到哪里。”
重构报错 API https://master-api.flutter.dev/flutter/foundation/ErrorSummary-class.html
报错信息下一步怎么做
对于 UI 代码抛出的报错信息,我们可以在信息中嵌入图像、动画甚至交互式的 widget 树,以最大化它的信息价值。我们计划在 Dart DevTools 的控制台上开展一些更宏大的试验,因为在那里我们不受 IntelliJ 和 VS Code 的可扩展性限制。
了解 Dart DevTools https://flutter.dev/docs/development/tools/devtools/overview
欢迎您来帮助我们
GitHub 问题跟踪专页 https://github.com/flutter/flutter/issues/new?labels=a:%20error%20message
鸣谢
扩展阅读 Dart Code https://dartcode.org/releases/v3-4/#improved-flutter-errors Flutter 社区中文资源 https://flutter-io.cn/
想了解更多 Flutter 内容?
在公众号首页发送关键词 “Flutter”,获取相关历史技术文章;
还有更多疑惑?欢迎点击菜单 “联系我们” 反馈您在开发过程中遇到的问题。
推荐阅读