提供有用的错误信息

——  高效程序员的 45 个习惯之习惯37

“不要吓着用户,吓程序员也不行。要提供给他们干净整洁的错误信息。要使用类似‘用户错误。替换,然后继续。’这样让人舒服的词句。”

当应用发布并且在真实世界中得到使用之后,仍然会发生这样那样的问题。比如计算模块可能出错,与数据库服务器之间的连接也可能丢失。当无法满足用户需求时,要以优雅的方式进行处理。

类似的错误发生时,是不是只要弹出一条优雅且带有歉意的信息给用户就足够了?并不尽然。当然了,显示通用的信息,告诉用户发生了问题,要好过由于系统崩溃造成应用执行错误的动作,或者直接关闭(用户会因此感到困惑,并希望知道问题所在)。然而,类似“出错了”这样的消息,无法帮助团队针对问题做出诊断。用户在给支持团队打电话报告问题时,我们希望他们提供足够多且好的信息,以帮助尽快识别问题所在。遗憾的是,用很通用的错误消息,是无法提供足够的数据的。

针对这个问题,常用的解决方案是记录日志:当发生问题时,让应用详细记录错误的相关数据。错误日志最起码应该以文本文件的形式维护。不过也许可以发布到一个系统级别的事件日志中。可以使用工具来浏览日志,产生所有日志信息的 RSS feed ,以及诸如此类的辅助方式。

记录日志很有用,可是单单这样做是不够的:开发人员认真分析日志,可以得到需要的数据;但对于不幸的用户来说,起不到任何帮助作用。如果展示给他们类似下图 中的信息,他们还是一点头绪都没有 —— 不知道自己到底做错了什么,应该怎么做可以绕过这个错误,或者在给技术支持打电话时,应该报告什么。

如果你注意的话,在开发阶段就能发现这个问题的早期警告。作为开发人员,经常要将自己假定为用户来测试新功能。要是错误信息很难理解,或者无助于定位错误的话,就可以想想真正的用户和支持团队,遇到这个问题时会有多么困难了(见图 7-2 )。

图 7-2  无用的异常信息

例如,假定登录 UI 调用了应用的中间层,后台向数据访问层发送了一个请求。由于无法连接数据库,数据访问层抛出一个异常。这个异常被中间层用自己的异常包裹起来,并继续向上传递。那么 UI 层应该怎么做呢?它至少应该让用户知道发生了系统错误,而不是由用户的输入引起的。

接下来,用户会打电话并且告诉我们他无法登录。我们怎么知道问题的实质是什么呢?日志文件可能有上百个条目,要找到相关的细节非常困难。

实际上,不妨在显示给用户的信息中提供更多细节。好比说,可以看到是哪条 SQL 查询或存储过程发生了错误;这样可以很快找到问题并且修正,而不是浪费大把的时间去盲目地碰运气。不过另一方面,在生产系统中,向用户显示数据连接问题的特定信息,不会对他们有多大帮助。而且有可能吓他们一跳。

一方面要提供给用户清晰、易于理解的问题描述和解释,使他们有可能寻求变通之法。另一方面,还要提供具备关于错误的详细技术细节给用户,这样方便开发人员寻找代码中真正的问题所在。

下面是一种同时实现上述两个目的方式:图中显示了清晰的错误说明信息。该错误信息不只是简单的文本,还包括了一个超链接。用户、开发人员、测试人员都可以由此链接得到更多信息,如图7-3 、图 7-4 所示。

图7-3 带有更多细节链接的异常信息

图 7-4  供调试用的完整详细信息

进入链接的页面,可以看到异常(以及所有嵌套异常)的详细信息。在开发时,我们可能希望只要看到这些细节就好了。不过,当应用进入生产系统后,就不能把这些底层细节直接暴露给用户了,而要提供链接,或是某些访问错误日志的入口。支持团队可以请用户点击错误信息,并读出错误日志入口的相关信息,这样支持团队可以很快找到错误日志中的特定细节。对于独立系统来说,点击链接,有可能会将错误信息通过电子邮件发送到支持部门。

除了包括出现问题的详细数据外,日志中记录的信息可能还有当时系统状态的一个快照(例如 Web 应用的会话状态)。

使用上述信息,系统支持团队可以重建发生问题的系统状态,这样对查找和修复问题非常有效。

错误报告对于开发人员的生产率,以及最终的支持活动消耗成本,都有很大的影响。在开发过程中,如果定位和修复问题让人倍受挫折,就考虑使用更加积极主动的错误报告方式吧。调试信息非常宝贵,而且不易获得。不要轻易将其丢弃。

展示有用的错误信息
提供更易于查找错误细节的方式。发生问题时,要展示出尽量多的支持细节,不过别让用户陷入其中。
区分错误类型
程序缺陷。 这些是真正的 bug ,比如 NullPointerException 、缺少主键等。用户或者系统管理员对此束手无策。

环境问题。 该类别包括数据库连接失败,或是无法连接远程 Web Services 、磁盘空间满、权限不足,以及类似的问题。程序员对此没有应对之策,但是用户也许可以找到变通的方法,如果提供足够详细的信息,系统管理员应该可以解决这些问题。

用户错误。 程序员与系统管理员不必担心这些问题。在告知是哪里操作的问题后,用户可以重新来过。

通过追踪记录报告的错误类型,可以为受众提供更加合适的建议。

切身感受

错误信息有助于问题的解决。当问题发生时,可以详细研究问题的细节描述和发生上下文。

平衡的艺术

  • 像“无法找到文件”这样的错误信息,就其本身而言无助于问题的解决。“无法打开 /andy/project/main.yaml 以供读取”这样的信息更有效。
  • 没有必要等待抛出异常来发现问题。在代码关键点使用断言以保证一切正常。当断言失败时,要提供与异常报告同样详细的信息。
  • 在提供更多信息的同时,不要泄露安全信息、个人隐私、商业机密,或其他敏感信息(对于基于 Web 的应用,这一点尤其重要)。
  • 提供给用户的信息可以包含一个主键,以便于在日志文件或是审核记录中定位相关内容。

[ ① ]    有些安全敏感的信息不应该被暴露,甚至不可以记录到日志中去,这其中包括密码、银行账户等。

【连载】优秀程序员的45个习惯之37——提供有用的错误信息相关推荐

  1. 优秀程序员的45个习惯

    优秀来自好的习惯.怎样成为优秀的开发人员?图灵公司最近热销的<高效程序员的45个习惯>一书给出了很好的解答,非常值得一读. 这本书的英文原版荣获了有软件奥斯卡之称的Jolt生产效率大奖,在 ...

  2. 转:优秀程序员的45个习惯

    今天看到这篇文章,觉得有我们要学习的地方,不过有几条不大符合中国的国情!!! 拿过来给大家看看. 优秀来自好的习惯.怎样成为优秀的开发人员?图灵公司最近热销的<高效程序员的45个习惯>一书 ...

  3. 优秀程序员的45个习惯[摘]

    引自  http://news.csdn.net/a/20100212/217004.html 态度篇 1. 做实事 不要抱怨,发牢骚,指责他人,找出问题所在,想办法解决.对问题和错误,要勇于承担. ...

  4. [转]优秀程序员的45个习惯

        态度篇 1. 做实事 不要抱怨,发牢骚,指责他人,找出问题所在,想办法解决.对问题和错误,要勇于承担. 2. 欲速则不达 用小聪明.权宜之计解决问题,求快而不顾代码质量,会给项目留下要命的死角 ...

  5. 【连载】优秀程序员的45个习惯之39——架构师必须写代码

    架构师必须写代码 --   高效程序员的 45 个习惯之习惯39 "我们的专家级架构师Fred会提供设计好的架构,供你编写代码.他经验丰富,拿的薪水很高,所以不要用一些愚蠢的问题或者实现上的 ...

  6. 【连载】优秀程序员的45个习惯之45——及时通报进展与问题

    好消息: 本书今天互动网有货,当当网.卓越网也会陆续有货. 及时通报进展与问题 -- 高效程序员的 45 个习惯之习惯45 "管理层.项目团队以及业务所有方,都仰仗你来完成任务.如果他们想知 ...

  7. 【连载】优秀程序员的45个习惯之42——允许大家自己想办法

    允许大家自己想办法 -- 高效程序员的 45 个习惯之习惯42 "你这么聪明,直接把干净利落的解决方案告诉团队其他人就好了.不用浪费时间告诉他们为什么这样做." "授人以 ...

  8. 【连载】优秀程序员的 45 个习惯之习惯35

    对问题各个击破 --  高效程序员的 45 个习惯之习惯35 "逐行检查代码库中的代码确实很令人恐惧.但是要调试一个明显的错误,只有去查看整个系统的代码,而且要全部过一遍.毕竟你不知道问题可 ...

  9. 【连载】优秀程序员的 45 个习惯之习惯33

    记录问题解决日志 -- 高效程序员的 45 个习惯之习惯33 "在开发过程中是不是经常遇到似曾相识的问题?这没关系.以前解决过的问题,现在还是可以解决掉的." 面对问题(并解决它们 ...

最新文章

  1. 知乎千万级高性能长连接网关是如何搭建的
  2. 图灵奖得主Judea Pearl :从“贝叶斯网络之父”到“AI社区的叛徒”
  3. MySQL三大范式详解(小白也能懂哦)
  4. 关于input file img实时预览获取文件路径的问题
  5. pycharm写python字典_pythonpycharm安装基础语法
  6. AOS编排语言系列教程(五):创建安全组SecurityGroup
  7. 1050 String Subtraction(20 分)
  8. 2021ccpc广州站总结
  9. 10 大开源免费的项目管理软件推荐
  10. 用python表白代码_使用Python制作表白小程序
  11. matlab的setup阶跃曲线图,matlab 绘制系统的单位阶跃响应曲线 并编写程序求峰值时间 超调量 | 学步园...
  12. 小白学python-决策树和随机森林
  13. “智慧新电商”全渠道获客+智能服务接待
  14. 《XX项目产品需求说明书-精华版》
  15. Hexo图片外链生成专用文章
  16. 使用kettle从mongodb导数据到mysql记录
  17. lower_bound()与upper_bound()
  18. RED5 1.0视频直播服务器 WINDOWS安装记录 教程
  19. 【mba项目管理论文】S 公司项目管理绩效评价现状与问题(节选)
  20. 2020G1工业锅炉司炉模拟考试系统及G1工业锅炉司炉操作证考试

热门文章

  1. python中int表示的数据类型是_python中的基本数据类型之 int bool str
  2. 服务器拷贝文件提示ms-dos功能无效,win7系统复制文件提示“MS-DOS功能无效”的解决方法...
  3. 《从零开始学Swift》学习笔记(Day 52)——Cocoa错误处理模式
  4. 物联网安全的后备计划是什么?
  5. 【以前的空间】主席树
  6. phoenix 开发API系列(三)phoenix api 结合数据库
  7. Android string.xml 通配符 %$用法
  8. 计算机培训校本研修心得,精选校本培训心得体会三篇
  9. linux网络健康度检测,linux运维、架构之路-K8s健康检查Health Check
  10. 如何在html页面循环回显数据,从while循环显示数据到html代码