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 扩展中,我们发布了一个新功能。这项功能能够以丰富而简洁的格式显示报错信息。日志记录控制台现在可以显示具备以下几项改进的报错信息:
用红色突出显示报错信息摘要
在节段之间添加空白,让信息更易于浏览
如果报错信息包含解决错误的提示,用高亮文字来让它们更突出
折叠信息中的长列表和树状图
我们如何做到这些改进
报错信息的可用性是一个多方面的问题。报错信息的内容、结构和呈现都有助于您理解报错并修复问题。我们知道 Flutter 中的报错信息通常会提供有用的内容,但是需要筛选的信息数量太大,从而容易错过有用的信息。 作为示例,我们来看看 “Missing Material widget” 这条报错信息。当 widget 在其祖先树中检索 Material widget 但未找到时,系统就会显示这条报错信息。这个报错的信息很难弄清楚, 甚至有用户专门去 StackOverflow 寻求帮助 。高票答案指出的关键信息其实已经包含在了报错信息中,只不过用户要么找不到所需的信息,要么无法理解。解决这个问题并不需要给出额外的信息。 △ StackOverflow 上关于 “找不到 Material widget” 的问题- 上文中提到的 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 个百分点。
△ 三种方案的 45 秒报错信息解读准确度 都明显高于原始格式同样,在确定解决方案时,报错信息的所有实验方案都优于原始格式。
△ 三种方案的报错信息解决准确度都明显高于原始格式
当我们要求参与者比较原始报错信息和他们在实验中使用的方案时,他们解释了为什么他们更喜欢这些新的报错呈现方案。以下是一些例子 (括号内的注释是笔者添加的)。“右边的报错消息 (指 ‘颜色’ 方案) 改进很明显,关键的短信息以红色显示,受影响的 widget 则以蓝色显示。” “隐藏整个 widget 对象 (指 ‘省略’ 方案) 可以减少干扰,我因此可以轻松找到报错发生的原因。” “B 方案 (指 ‘分段’ 方案) 更容易理解。这些分段非常明晰,我在快速浏览时很容易知道下一步要跳到哪里。”有了实验得出的有力证据,我们决定针对结构化报错信息进行资源投入。这是一段漫长的旅程,但我们很高兴地看到, 重构的报错 API 为未来的创新提供了坚实的基础,帮助开发者更快地修复 Flutter 项目中的错误。
- 重构报错 APIhttps://master-api.flutter.dev/flutter/foundation/ErrorSummary-class.html
报错信息下一步怎么做
对于 UI 代码抛出的报错信息,我们可以在信息中嵌入图像、动画甚至交互式的 widget 树,以最大化它的信息价值。我们计划在 Dart DevTools 的控制台上开展一些更宏大的试验,因为在那里我们不受 IntelliJ 和 VS Code 的可扩展性限制。
- 了解 Dart DevToolshttps://flutter.dev/docs/development/tools/devtools/overview
欢迎您来帮助我们
部分 Flutter 报错信息还没有用新的 API 进行重构,因此它们暂时无法充分利用这种新的结构化呈现方式。我们正在优先处理覆盖面最广的 Flutter 报错信息。您可以通过 我们的 GitHub 问题跟踪专页 让我们知道哪些报错信息更有用,或是在我们的 IntelliJ 和 VS Code 插件的代码库中提出改进报错信息呈现方式的建议。- GitHub 问题跟踪专页https://github.com/flutter/flutter/issues/new?labels=a:%20error%20message
鸣谢
Flutter 团队的前 UX 研究实习生 Kandarp Khandwala 为本文所述的研究做出了积极贡献。我们还要感谢所有参与实验的 Flutter 开发者。- 扩展阅读 Dart Codehttps://dartcode.org/releases/v3-4/#improved-flutter-errors
- Flutter 社区中文资源https://flutter-io.cn/
点击屏末 | 阅读原文 | 即刻开启 Flutter 开发之旅
想了解更多 Flutter 内容?
在公众号首页发送关键词 “Flutter”,获取相关历史技术文章;
还有更多疑惑?欢迎点击菜单 “联系我们” 反馈您在开发过程中遇到的问题。
推荐阅读