【问题标题】:internal error markers内部错误标记
【发布时间】:2010-09-24 00:50:00
【问题描述】:

理论上,最终用户永远不会看到内部错误。但在实践中,理论和实践是不同的。所以问题是向最终用户展示什么。现在,对于完全非技术用户,您希望尽可能少地显示(“单击此处提交错误报告”之类的东西),但对于更高级的用户,他们会想要知道是否有解决方法,是否已经知道了一段时间等。因此,您还希望包含一些关于问题所在的信息。

执行此操作的经典方法是使用文件名:行号的断言或使用相同的堆栈跟踪。现在这对开发人员来说是件好事,因为它把问题指向了他;但是它对用户来说有一些明显的缺点,特别是它非常神秘(例如不友好)并且代码更改会更改错误消息(谷歌搜索错误仅适用于此版本)。

我计划编写一个程序来解决这些问题。我想要的是一种将唯一身份附加到每个断言的方法,这样编辑断言周围的代码不会改变它。 (例如,如果我将它剪切/粘贴到另一个文件,我希望显示相同的信息)有什么想法吗?

我正在考虑的一种方法是对错误进行枚举,但如何确保它们永远不会在多个地方使用?

(注意:对于这个问题,只查看由编码错误引起的错误。而不是像错误输入这样合法发生的事情。OTOH 这些错误可能会引起一些兴趣整个社区。)

(注 2:有问题的程序将是在用户系统上运行的命令行应用程序。但同样,这只是我的情况。)

(注 3:目标语言是 DI'm very willing 以深入了解 meta-programming。非常欢迎其他语言的答案!)

(注 4:我明确希望不使用实际代码位置,而是使用某种符号名称来表示错误。这是因为如果代码以任何方式更改,代码位置也会发生变化。)

【问题讨论】:

    标签: error-handling user-experience error-reporting


    【解决方案1】:

    有趣的问题。我多次使用的解决方案是:如果是致命错误(例如,非致命错误应该让用户有机会更正输入),我们会生成一个包含大量相关信息的文件:请求变量,标头、内部配置信息和完整的回溯,以供以后调试。我们将其存储在具有生成的唯一文件名的文件中(并以时间作为前缀)。

    对于用户,我们会提供一个页面,说明发生了不可恢复的错误,并要求他们在报告错误时包含文件名作为参考。使用来自违规请求的上下文中的所有这些信息进行调试要容易得多。

    在 PHP 中,debug_backtrace() 函数对此非常有用。我敢肯定你的平台有一个等价物。

    还要记得发送相关的http头:可能是:HTTP/1.1 500 Internal Server Error

    给定错误报告文件的合理格式,还可以分析用户未报告的错误。

    【讨论】:

    • 另外,考虑一下进入这个文件的内存记录器之类的东西。
    • 不幸的是,我没有该语言的跟踪系统:(
    【解决方案2】:

    编写一个脚本来 grep 整个源代码树以使用这些错误代码,然后在有重复项时进行投诉。将该脚本作为单元测试的一部分运行。

    【讨论】:

    • 一个很好的回退,但我宁愿让这种错误破坏构建或更快的反馈。
    • @BCS:然后将检查作为构建的一部分而不是单元测试的一部分运行:D
    【解决方案3】:

    我对你的目标语言一无所知,但这是一个有趣的问题,我已经考虑过,我想加两分钱。

    我的感觉一直是硬错误和内部错误的消息应该尽可能有用,以便开发人员识别问题并快速修复它。大多数用户甚至不会查看此错误消息,但高度复杂的最终用户(可能是技术支持人员)通常会很好地了解问题所在,甚至通过查看非常详细的错误消息来提出新颖的解决方法。关键是让这些错误信息详细而不神秘,这更像是一门艺术而不是一门科学。

    一个使用进程外 COM 服务器的 Windows 程序示例。如果主程序尝试从 COM 服务器实例化一个对象并失败并显示错误消息:

    "警告:无法实例化 UtilityObject:错误'类不是 在 'CoCreateInstance' 中注册'"

    99% 的用户会看到此内容并认为它是用希腊语编写的。技术支持人员可能很快意识到他们需要重新注册 COM 服务器。并且开发人员会确切地知道出了什么问题。

    为了将一些上下文信息与断言相关联,在我的 C++ 代码中,我经常使用带有方法名称的简单字符串,或者其他可以明确错误发生位置的字符串(我很抱歉在您没有询问的语言):

    int someFunction()
    {
      static const std::string loc = "someFunction";
      :  :
      if( somethingWentWrong )
      {
        WarningMessage(loc.c_str(), "Unable to Instantiate UtilityObject:  Error 'Class Not
        Registered' in 'CoCreateInstance);
      }
    }
    

    ...生成:

    警告 [someFunction]:无法 实例化 UtilityObject:错误 '类未注册'在 'CoCreateInstance

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 1970-01-01
      相关资源
      最近更新 更多