为什么大多数异常都会忽略特定于实例的信息?

时间:2011-12-12 15:28:57

标签: c# .net exception

我注意到大多数异常消息都不包含特定于实例的详细信息,例如导致异常的值。他们通常只告诉你错误的“类别”。

例如,尝试使用3rd进行序列化对象时。派对库,我收到了一条带有消息的MissingMethodException:

  

“没有为此对象定义无参数构造函数。”

在许多情况下,这已足够,但通常(通常在开发期间)消息如

  

“没有为'Foo'类型的对象定义无参数构造函数。”

可以通过直接指导错误原因来节省大量时间。

InvalidArgumentException是另一个例子:它通常告诉你参数的名称而不是它的值。 这似乎是大多数框架引发的异常,也适用于第三方库。

这是故意这样做的吗?

在暴露内部状态(如变量的“错误”值)时是否存在安全隐含?

4 个答案:

答案 0 :(得分:4)

InvalidArgumentException和(@Ian Nelson)“字典中找不到密钥”两者有共同之处 - 无法保证框架能够找到合适的值来显示 - 如果密钥/参数是任何用户定义的类型,并且ToString()没有被覆盖,那么你只需要获取类型名称 - 它不会增加很多价值。

答案 1 :(得分:4)

我能想到的两个原因:

首先,抛出异常的参数可能是一个值,该值是传递给公共接口的处理形式。如果不重新考虑重新抛出在大多数方面都会相同的不同异常,这个价值可能没有意义。

其次,更重要的是,确实存在安全风险,可能很难进行二次猜测(如果我正在编写一个通用容器,我不知道它会是什么样的背景用于)。如果我们能提供帮助,我们不希望“信用卡:5555444455554444”出现在错误消息中。

最终,调试信息最有用的将根据错误而有所不同。如果类型,方法和(如果可能的话)文件和行号不够,是时候写一些调试代码来捕获你想知道的内容,而不是抱怨下次你没有被困可能还需要不同的信息(实例的字段状态可能与参数一样有用)。

答案 2 :(得分:2)

例外主要用于程序消费。大多数程序都不知道如何处理有关该实例的信息。

Message财产旨在供人食用。除了在调试场景中,人类不知道该怎么做Foo

答案 3 :(得分:1)

许多异常机制试图通过传递单个异常派生对象来提供正交目的的大杂烩:

  1. 让来电者知道发生了各种具体事情,或者存在各种具体问题。
  2. 确定异常情况何时“已解决”,以便正常的程序流程可以继续。
  3. 提供告诉用户该程序的内容的指示
  4. 提供可记录的信息,以便在安全日志可用时允许系统所有者识别问题
  5. 提供可记录的信息,以允许系统所有者识别问题,但即使安全日志记录不可用,也不会带来安全风险。

不幸的是,我没有意识到广泛使用的任何异常机制,它实际上可以完成以上所有五个。