异常不包含有用的细节,因为在软件工程领域内,异常的概念还不够成熟,因此许多程序员无法完全理解它们,因此不能正确对待它们。
是的,IndexOutOfRangeException
应该包含超出范围的精确索引,以及在抛出该索引时有效的范围,对于.NET运行时的创建者而言,它不是可鄙的。是的,Oracle的table or view not found
异常应包含未找到的表或视图的名称,并再次代表不负责任的人可以轻视它的事实。
很大程度上,这种混淆源于误导性的原始观念,即异常应该包含人类可读的消息,而这又又是由于缺乏对异常的含义的理解,因此这是一个恶性循环。
由于人们认为该异常应包含一条人类可读的消息,因此他们认为该异常所携带的任何信息也应被格式化为该人类可读的消息,然后他们要么无聊就写了所有人类可读的消息,构建代码,否则他们担心这样做可能会将不明智的信息泄露给任何窥探者可能看到的消息。(其他答案提到的安全性问题。)
但是,事情的真相是,他们不应该担心,由于异常应不包含人类可读的消息。异常是只有程序员才能看到和/或处理的东西。如果需要将故障信息呈现给用户,则必须以非常高的级别,以一种复杂的方式并以用户的语言来完成,从统计上讲,这不太可能是英语。
所以,对我们的程序员,在异常的“消息”是类名称的异常,以及其它信息相关的异常应该被复制到异常对象(最终/只读)成员变量。优选地,每个可能的一点点。这样,不需要(或不应该)生成任何消息,因此,任何撬动的眼睛都看不到它。
为了解决托马斯·欧文斯在以下评论中表达的关注:
是的,当然,在某种程度上,您将创建有关该异常的日志消息。但是您已经看到了问题所在:一方面,没有堆栈跟踪的异常日志消息没有用,但另一方面,您不想让用户看到整个异常堆栈跟踪。同样,这里的问题是我们的观点受到传统做法的歪曲。传统上,日志文件采用纯文本格式,这在我们尚处于起步阶段时可能还不错,但也许不再适用:如果出于安全考虑,则日志文件必须为二进制和/或加密的。
不管是二进制文本还是纯文本,都应将日志文件视为应用程序将调试信息序列化到其中的流。这样的流只会供程序员使用,并且为异常生成调试信息的任务应该与将异常序列化到调试日志流中一样简单。这样,通过查看日志,您可以看到异常类名称(正如我已经说过的,它实际上是“消息”,)每个异常成员变量都描述了与以下内容相关的所有内容:并在实际中包含日志,以及整个堆栈跟踪。请注意,此过程中如何明显地缺少人类可读异常消息的格式。
聚苯乙烯
我可以在以下答案中找到关于该主题的更多想法:如何编写良好的异常消息
PPS
我对二进制日志文件的建议似乎使很多人不满意,因此我再次修改了答案,以使我更加清楚地表明,我在这里建议的不是日志文件应为二进制,而是如果需要,日志文件可以是二进制文件。