代码之家  ›  专栏  ›  技术社区  ›  Swingline Rage

区分.NET异常类型

  •  13
  • Swingline Rage  · 技术社区  · 14 年前

    对于所有神圣事物的热爱,您如何区分预定义的.NET异常类中不同的“异常风格”?

    例如,一段代码可能会抛出 XmlException 在下列条件下:

    • 文档的根元素为空
    • 文档中包含无效字符
    • 文件太长了

    所有这些都被当作 XML异常 对象和所有内部“告诉我有关此异常的更多信息”字段(例如 Exception.HResult , Exception.Data 等)通常为空或空。

    那叶子 Exception.Message 作为唯一能让你区分这些异常类型的东西,你不能真正依赖它,因为,你猜,它 异常。消息 字符串是光彩夺目的,并且可以随着文化的变化而改变。至少这是我读到的 documentation .

    异常.hresult 异常数据 在.NET库中被广泛忽略。他们是全球.NET错误处理代码的红头发继子。即使假设他们不是的话, HRESULT 类型仍然是错误代码历史上最糟糕、最糟糕的错误代码。为什么我们仍然关注2010年的结果超出了我的理解范围。我的意思是如果你在做互操作或者P/Invoke,这是一件事,但是……hresults在system.exception中没有位置。hresults是System.Exception的探针上的疣。

    但说真的,这意味着我必须制定很多详细的 具体的 错误处理代码,以便找出作为异常数据一部分传递的相同信息。如果他们强迫你这样工作,例外是没用的。我做错什么了?

    编辑。一天后。

    感谢所有的评论和回复。我在这里学到了一个一般性的教训(“错误消息太糟糕了”),即使我还没有完全解决具体的问题。下面是我将要面对的具体情况。

    我们的应用程序使用由第三方生成的XML文件。这些XML文件有时包含非法字符,这些字符实际上在XML文件中没有业务。这些非法字符导致(正在验证)xmlReader爆炸为“第x行的非法字符”exception。但是,我们必须处理这些文件;我们不能简单地告诉用户,“对不起,这个文件不符合官方的XML规范。”我们的用户甚至不知道什么是XML。

    在这种情况下(XML文档包含非法字符的情况下),微软有一个正式的(对我来说很奇怪)建议:将文件加载到流中,迭代到包含错误的特定行(具有讽刺意味的是,在xmleexception对象中提供),并自定义将有问题的字符替换为合法的字符。然后再次尝试将文档加载到验证XML阅读器中,并查看它是否爆炸。这里是 Knowledge Base article 描述技术。

    很好,我们正在做,而且效果很好。问题是,有时我们得到的这些XML文件在其他方面的格式不正确:它们可能是空的,可能缺少结束标记等。因此,如果您遵循MS建议,实际上是将“替换非法字符”逻辑挂接到catch块中,在该块中捕获验证读取器引发的原始异常。

    如果这个异常实际上是一个“非法字符”异常,那就好了。但是如果它是一个“根元素丢失”或“缺少结束标记”异常,那么您会发现MS技术将进入并替换有问题的字符 它本身 爆炸,因为不仅没有一个令人讨厌的字符,根本没有字符,或者有字符,但是它们是无效的XML格式,或者其他什么。此时,您正处于一个双嵌套的catch-inside-a-catch中,您的头发变得灰白并脱落,您的眼睛因咖啡因疲劳而深红,并且您在质疑使用真实XML验证读卡器的合理性,更不用说实用性了。

    所以我需要一种方法来说明,在初始catch(xmlException)块中,这是一个“缺少根元素”还是一个“无效char”异常,所以我可以采取适当的操作。我们不能做的一件事是阻止我们的用户打开包含一些无效字符的文档。不管怎样,我们都必须处理这些文档,我想唯一的解决方案是提前遍历文档中的每个字符,将其视为文本流而不是XML,找到非法字符,替换它们,然后用验证性的xmlReader加载它,如果它崩溃了,我们知道它是 一个非法字符异常,因为我们预先除去了非法字符。

    在这样做之前,我想我至少要问1)我们能从xmleException对象中得到更好的信息吗?我希望有人会告诉我2)“可以关闭xmleException.message字符串。他们说它是本地化的,但实际上不是。此字符串在Windows的所有版本和区域性中都是相同的。”

    但没人告诉我。

    3 回复  |  直到 13 年前
        1
  •  7
  •   Eric Petroelje    14 年前

    原则上我完全同意您的观点,但是我真正关心异常被抛出(在我的代码中)的确切原因的实例数量非常小。

    以xmlException为例,如果文档太长,您的代码中是否真的会有一些不同的行为?如果文档包含无效字符,您会有什么不同的行为?

    我能想到的唯一一个真正关心的例子是SQL类型异常,其中一些错误可以从中恢复(例如丢失的数据库连接)。

    埃塔:

    如果在键入错误消息时担心区域性,可以在处理文档时将当前线程区域性设置为不变区域性,然后在完成后将其设置回原始区域性。这应该确保消息始终是相同的。

        2
  •  4
  •   David Basarab    14 年前

    这里的问题似乎是你从中得到的不好的信息 XmlException . 这是一个API设计问题。

    一个选项使用不同于 System.Xml System.Xml.Linq 并使用xdocument查看是否获得更好的错误代码。

    如果这些都不起作用,那么您可以使用开源XML解析器,例如 NDigester 并修改代码以给出更详细的错误。

        3
  •  1
  •   supercat    13 年前

    听起来需要的是一个XML解析例程,它不是在发生解析错误时抛出异常,而是调用传入的委托。如果委托接受与解析状态相关的信息,它可以尝试进行任何必要的修正,并返回一个值,指示应该重新评估文件中有问题的部分。

    为此目的设计一个好的委托接口(一组参数和调用约定)可能很困难,但这样的系统可以更有效地通过损坏的文件摸索,而不是抛出异常的文件。