理论上,最终用户永远不应该看到内部错误。但在实践中,理论和实践有所不同。所以问题是如何向最终用户展示。现在,对于完全非技术性的用户,您希望尽可能少地展示(“点击此处提交错误报告”类似的东西),但对于更高级的用户,他们希望知道是否有解决方法,如果它已经知道了一段时间等等。所以你想要包含一些类型的信息,以及错误。
执行此操作的经典方法是使用文件名的断言:行号或具有相同的堆栈跟踪。现在这对开发人员有好处,因为它指出了他正确的问题;但它对用户有一些重大的缺点,特别是它非常神秘(例如不友好),代码更改会更改错误消息(Googling for the error仅适用于此版本)。
我有一个我正计划编写的程序,我想解决这些问题。我想要的是一种将唯一标识附加到每个断言的方法,以便编辑断言周围的代码不会改变它。 (例如,如果我将其剪切/粘贴到另一个文件,我希望显示相同的信息)任何想法?
我想到的一个方法是对错误进行枚举,但是如何确保它们不会在多个地方使用?
(注意:对于这个问题,我只查看由编码错误引起的错误。不是可能合理地发生的错误输入.OTOH这些错误可能对某些感兴趣整个社区。)
(注2:有问题的程序将是在用户系统上运行的命令行应用程序。但同样,这只是我的情况。)
(注3:目标语言为D和I'm very willing以便潜入meta-programming。其他语言的答案非常受欢迎!)
(注4:我明确地希望不使用实际代码位置,而是使用某种符号名称来表示错误。这是因为如果代码几乎以任何方式被更改,代码位置就会发生变化。)
答案 0 :(得分:2)
有趣的问题。我曾多次使用的解决方案是:如果这是一个致命的错误(非致命错误应该让用户有机会纠正输入,例如),我们生成一个包含大量相关信息的文件:请求变量,标头,内部配置信息和完整的回溯以供以后调试。我们将其存储在一个文件中,该文件具有生成的唯一文件名(并以时间作为前缀)。
对于用户,我们提供一个页面,说明发生了不可恢复的错误,并要求他们包含文件名作为参考,如果他们想报告错误。使用违规请求的上下文中的所有这些信息进行调试会更加容易。
在PHP中,debug_backtrace()函数对此非常有用。我相信你的平台有一个等价物。
还记得发送相关的http标头:可能是:HTTP / 1.1 500内部服务器错误
鉴于错误报告文件的合理格式,还可以分析用户未报告的错误。
答案 1 :(得分:1)
编写一个脚本来grep整个源代码树以使用这些错误代码,然后抱怨是否有重复项。将该脚本作为单元测试的一部分运行。
答案 2 :(得分:1)
我对你的目标语言一无所知,但这是一个有趣的问题,我已经考虑过了,我想加上我的两分钱。
我的感觉一直是,硬错误和内部错误的消息应尽可能有用,以便开发人员识别问题&快速解决它。大多数用户甚至不会看到这个错误消息,但是高度复杂的最终用户(可能是技术支持人员)通常会很好地了解问题所在,甚至通过查看非常详细的错误消息来提出新颖的解决方法。关键是要将这些错误信息详细描述而不是神秘的,这更像是一门艺术,而不是一门科学。
使用进程外COM服务器的Windows程序示例。如果主程序试图从COM服务器实例化一个对象并失败并显示错误消息:
“警告:无法实例化 UtilityObject:错误'Class Not 注册'in'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的