54.3. 错误消息样式指南

提供该样式指南的目的是希望在 PostgreSQL 生成的所有消息中保持一致,用户友好的样式。

哪里去了

主要消息应简短,真实,并避免引用实现细节,例如特定的函数名称。 “短”表示“在正常情况下应放在一条线上”。如果需要使主要消息简短,或者如果您需要提及实现详细信息(例如失败的特定系统调用),请使用详细信息。主要消息和详细消息都应该是事实消息。使用提示消息来建议有关解决问题的方法的建议,尤其是在建议可能并不总是适用的情况下。

例如,代替:

IpcMemoryCreate: shmget(key=%d, size=%u, 0%o) failed: %m
(plus a long addendum that is basically a hint)

write:

Primary:    could not create shared memory segment: %m
Detail:     Failed syscall was shmget(key=%d, size=%u, 0%o).
Hint:       the addendum

基本原理:将主要消息保持简短有助于将问题保持在正确的位置,并允许 Client 在一行显示错误消息的前提下布置屏幕空间。详细信息和提示消息可以降级为详细模式,或者可能弹出错误详细信息窗口。此外,通常会从服务器日志中删除详细信息和提示以节省空间。最好避免参考实现细节,因为不希望用户知道细节。

Formatting

不要在消息文本中加入关于格式的任何特定假设。期望 Client 端和服务器日志可以换行以适应他们自己的需求。在长消息中,换行符( n)可用于指示建议的段落分隔符。不要以换行符结束消息。不要使用制表符或其他格式字符。 (在错误上下文显示中,换行符会自动添加到单独的上下文级别,例如函数调用.)

基本原理:消息不一定显示在终端类型的显示器上。在 GUI 显示或浏览器中,这些格式化说明最多只能忽略。

Quotation Marks

引用适当时,英文文本应使用双引号。其他语言的文本应始终使用与发布习惯和其他程序的计算机输出一致的一种引号。

理由:双引号而不是单引号的选择在某种程度上是任意的,但往往是首选。有人建议根据 SQL 约定根据对象的类型选择引号的类型(即字符串单引号,标识符双引号)。但这是语言内部的技术问题,许多用户甚至都不熟悉,它不能扩展到其他种类的引用术语,也不能翻译成其他语言,而且也毫无意义。

报价使用

始终使用引号来分隔文件名,用户提供的标识符以及其他可能包含单词的变量。不要使用它们来标记不包含单词的变量(例如,运算符名称)。

后端中的函数会根据需要对自己的输出加双引号(例如format_type_be())。不要在此类函数的输出周围加上其他引号。

基本原理:对象可以具有在嵌入消息中时会产生歧义的名称。关于表示插入名称的开始和结束位置要保持一致。但是,请勿使带有不必要或重复引号的邮件混乱。

语法和标点

对于主要错误消息和详细信息/提示消息,规则是不同的:

主要错误消息:不要将首字母大写。不要以句号结束消息。甚至不要考虑以感叹号结束消息。

详细信息和提示消息:使用完整的句子,并以句号结尾。将句子的第一个单词大写。如果后面再加上一个句子,则在句号后放置两个空格(对于英文文本;在其他语言中可能不合适)。

错误上下 Literals 符串:不要将首字母大写,也不要以句号结尾。上下 Literals 符串通常不应该是完整的句子。

基本原理:避免使用标点符号,可使 Client 端应用程序更轻松地将消息嵌入各种语法上下文中。通常,主要消息无论如何都不是语法完整的句子。 (并且,如果它们足够长而不能超过一个句子,则应将它们分为主要部分和详细部分.)但是,详细信息和提示消息较长,可能需要包含多个句子。为了保持一致性,即使只有一句话,他们也应遵循完整句子的风格。

大写与小写

使用小写形式表示消息,包括主要错误消息的首字母。如果 SQL 命令和关键字出现在消息中,请使用大写字母。

原理:以这种方式使所有内容看起来更加一致更加容易,因为有些消息是完整的句子,而有些则不是。

避免被动语态

使用主动语音。当有表演主体时使用完整的句子(“ A 不能做 B”)。如果主题是程序本身,则使用不带主题的电报样式;请勿在程序中使用“ I”。

理由:该程序不是人类。别 Feign。

现在时与过去时

如果尝试做某事失败,请使用过去时,但下次可能成功(也许在解决某些问题之后)。如果失败肯定是永久的,请使用现在时。

形式的句子之间存在不平凡的语义差异:

could not open file "%s": %m

and:

cannot open file "%s"

第一个意味着打开文件的尝试失败。该消息应给出原因,例如“磁盘已满”或“文件不存在”。过去式是适当的,因为下次磁盘可能不再满,或者相关文件可能存在。

第二种形式表示打开命名文件的功能在程序中根本不存在,或者从概念上讲是不可能的。现在时是适当的,因为条件会无限期地持续下去。

基本原理:当然,普通用户将无法仅从消息的时态中得出重大结论,但是由于该语言为我们提供了语法,因此我们应该正确使用它。

对象类型

引用对象名称时,请说明对象的类型。

基本原理:否则,没人会知道“ foo.bar.baz”指的是什么。

Brackets

方括号仅用于(1)在命令摘要中表示可选参数,或(2)表示数组下标。

理由:其他任何事情都不符合众所周知的习惯用法,会使人们感到困惑。

组装错误消息

当邮件中包含在其他位置生成的文本时,请以以下样式嵌入:

could not open file %s: %m

原理:很难解决所有可能的错误代码,以将其粘贴到单个平滑语句中,因此需要某种标点符号。也有人建议将嵌入的文本放在括号中,但通常情况下,如果嵌入的文本可能是消息中最重要的部分,那是不自然的。

错误原因

消息中应始终指出发生错误的原因。例如:

BAD:    could not open file %s
BETTER: could not open file %s (I/O failure)

如果不知道原因,则最好修复该代码。

Function Names

不要在错误文本中包含报告例程的名称。我们还有其他机制可以在需要时进行查找,对于大多数用户而言,这并不是有用的信息。如果没有函数名称,错误文本的意义不大,则将其 Rewrite。

BAD:    pg_atoi: error in "z": cannot parse "z"
BETTER: invalid input syntax for integer: "z"

避免提及任何被称为函数的名称;而是说代码要做什么:

BAD:    open() failed: %m
BETTER: could not open file %s: %m

如果确实有必要,请在详细消息中提及系统调用。 (在某些情况下,提供传递给系统调用的实际值可能是详细消息的适当信息.)

基本原理:用户不知道所有这些功能做什么。

棘手的话要避免

无法使用. “无法使用”几乎是被动语态。适当时,最好使用“不能”或“不能”。

不良. 诸如“不良结果”之类的错误消息确实很难明智地解释。最好写出结果为何“不正确”(例如“无效格式”)的信息。

非法. “非法”代表违法,其余为“无效”。更好的是,说出它为什么无效。

未知. 尽量避免“未知”。考虑“错误:未知响应”。如果您不知道响应是什么,您怎么知道它是错误的? “无法识别”通常是一个更好的选择。另外,请确保包括抱怨的价值。

BAD:    unknown node type
BETTER: unrecognized node type: 42

查找与存在 。如果程序使用非平凡的算法来定位资源(例如,路径搜索)并且该算法失败,则可以说程序无法“查找”资源。另一方面,如果知道资源的预期位置,但是程序无法在那里访问资源,则说资源“不存在”。在这种情况下,使用“查找”听起来很弱,并且使问题感到困惑。

五月与可能与可能. “五月”表示允许(例如,“您可以借用我的耙子.”),并且在文档或错误消息中很少使用。 “可以”表示能力(例如,“我可以举起那条日志”.),“可能”表示可能性(例如,“今天可能下雨”)。使用适当的词可以使含义更清楚,并有助于翻译。

收缩. 避免收缩,例如“不能”;使用“不能”代替。

Proper Spelling

完全拼出单词。例如,避免:

  • spec

  • stats

  • parens

  • auth

  • xact

理由:这将提高一致性。

Localization

请记住,错误消息文本需要翻译成其他语言。请遵循Section 55.2.2中的指南,以免使翻译人员感到困难。