使用InvariantCulture或CurrentCulture格式化异常消息?

3

当抛出异常时,我经常传递一个格式化的字符串,以暴露发生的问题的细节。如果可能的话,我总是指定一个格式提供程序(这是一个好习惯,因为否则你可能会忘记决定哪个文化是合适的,而默认值是当前文化,这可能会导致许多错误)。

以下是一个例子:

throw new InvalidOperationException(
    string.Format(
        CultureInfo.CurrentCulture,
        "{0} is a bad number.",
        number));

我倾向于使用CurrentCulture,如上所示,因为异常消息是针对人类的(当然,代码不应该直接操作异常消息)。消息将使用客户端的文化进行格式化,因此每当我需要向客户端显示它时,它看起来很好。
然而,除了向用户显示消息外,异常可能也会被记录到日志文件中。我看过许多消息坐落在我的日志文件中,并使用各种文化进行格式化。非常丑陋!在这种情况下,InvariantCulture可能更合适,或者使用托管日志文件的服务器的文化。
关键在于,在格式化异常时,您永远无法确定您的受众,因此似乎不可能决定在格式化时使用哪种文化。能够将格式化推迟到捕获异常的点将是很好的,但那将远远超出.NET中实现异常的方式。
那么你对此有什么想法呢?
2个回答

5
由于异常信息是英文的,我建议使用不变的文化。为什么要将英文文本与非英文数字格式混合呢?
如果您决定本地化异常消息(就像.NET框架一样),那么您需要使用所选资源程序集的文化。这可以确保数字格式和语言匹配,即使没有本地化可用(即回退到英语)。
然而,在我看来,异常消息主要是针对开发人员的。因此,除非是来自世界各地的开发人员的大型项目,否则我不会考虑本地化它们。如果您无法处理异常,则应捕获它并提供适合给定上下文的用户错误消息(可能或可能不如异常消息精确)。
向他们提供异常消息本身可能会(特别是对于Web服务器)暴露有关服务器软件的详细信息,这可能会被恶意使用。我认为最好记录异常并向用户提供(本地化的)错误消息和一些数据,以便将日志事件(最可能是不本地化的、不变的文化)与他们的反馈相关联。
例如,WCF不会向用户报告异常细节,除非明确配置为这样。请参见IncludeExceptionDetailInFaults配置设置和其中的“注意”块。

1
谢谢,这些是很好的论点。我之前考虑过在捕获未处理异常时(例如在ASP.NET中的global.asax中)向用户显示异常消息,但我同意记录异常并显示通用(本地化)消息会更好。这种方法使整个故事变得简单:始终使用InvariantCulture格式化异常消息,永远不要将消息暴露给客户端。 - Sandor Drieënhuizen

1

我认为您可以使用异常类的“Data”属性。这样,您可以在“Message”属性中存储不变的消息以进行日志记录。并且您可以向“Data”集合添加一个键值对,其中Key =“UIMessage”,Value =根据用户文化适当格式化的UI消息(可能是根据正确文化翻译的消息)。然后,在您的异常处理程序中,您只需要在消息属性和数据对之间选择,以便记录或显示适当的消息。


那是一个有趣的想法。 - Sandor Drieënhuizen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接