Error handling 内部错误标记

Error handling 内部错误标记,error-handling,user-experience,error-reporting,Error Handling,User Experience,Error Reporting,理论上,最终用户永远不会看到内部错误。但在实践中,理论和实践有所不同。所以问题是向最终用户展示什么。现在,对于完全非技术性的用户,您希望尽可能少地显示(“单击此处提交错误报告”之类的内容),但是对于更高级的用户,他们希望知道是否有解决方法,是否已经知道了一段时间,等等。因此,您还希望包含一些关于错误的信息 实现这一点的经典方法是使用文件名为:行号的断言或使用相同文件名的堆栈跟踪。现在这对开发者来说是好的,因为它正好指出了问题所在;但是,它对用户有一些明显的缺点,特别是它非常神秘(例如不友好),代

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

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

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

我想到的一个方法是对错误进行枚举,但是如何确保它们从不在多个地方使用

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

(注2:所讨论的程序将是一个在用户系统上运行的命令行应用程序。但同样,这只是我的情况。)

(注3:目标语言为和。欢迎回答其他语言!)


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

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

对于用户,我们提供了一个页面,解释发生了不可恢复的错误,并要求他们在报告错误时包含文件名作为参考。从有问题的请求的上下文中调试所有这些信息要容易得多

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

还要记住发送相关的http头:可能是:http/1.1500内部服务器错误


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

编写一个脚本,对整个源代码树使用这些错误代码进行grep,然后如果存在重复的错误代码,则进行投诉。作为单元测试的一部分运行该脚本。

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

我一直认为,对于开发人员来说,硬错误和内部错误的消息应该尽可能有用,以识别问题并快速修复。大多数用户甚至不会查看此错误消息,但高度复杂的最终用户(可能是技术支持人员)通常会通过查看高度详细的错误消息来了解问题所在,甚至会想出新颖的解决方法。关键是要使这些错误信息详细而不晦涩,这与其说是一门科学,不如说是一门艺术

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

“警告:无法实例化 UtilityObject:错误“类不可用” 已在“CoCreateInstance”中注册

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

<>为了将一些上下文信息与断言相关联,在我的C++代码中,我经常使用一个简单的字符串,用方法的名称,或者其他明确的地方指出错误发生的地方(我用你没有问的语言回答):

…这将产生:

警告[someFunction]:无法删除 实例化UtilityObject:错误 中的“类未注册” '协同创建实例


同样,考虑到内存中的记录器进入这个文件。不幸的是,我没有语言中的跟踪系统:(一个好的回落,但是我宁愿这种错误打破构建或更快的反馈。@ BCS:然后运行检查作为构建的一部分,而不是单元测试的一部分:D。
int someFunction()
{
  static const std::string loc = "someFunction";
  :  :
  if( somethingWentWrong )
  {
    WarningMessage(loc.c_str(), "Unable to Instantiate UtilityObject:  Error 'Class Not
    Registered' in 'CoCreateInstance);
  }
}