Postgresql 中文操作指南
56.2. Reporting Errors Within the Server #
服务器代码中生成的错误、警告和日志消息应使用 ereport,或其较早版本 elog 创建。此函数的使用很复杂,需要一些解释。
Error, warning, and log messages generated within the server code should be created using ereport, or its older cousin elog. The use of this function is complex enough to require some explanation.
每条消息有两个必需的元素:严重性级别(范围从 DEBUG 到 PANIC)和主要消息文本。此外,还有一些可选元素,其中最常见的是一个遵循 SQL 规范的 SQLSTATE 约定的错误标识符代码。ereport 本身只是一个外壳宏,其主要存在是为了语法方便,使得消息生成在 C 源代码中看起来像一个函数调用。ereport 直接接受的唯一参数是严重性级别。主要消息文本和任何可选消息元素都是通过在 ereport 调用中调用辅助函数(如 errmsg)来生成的。
There are two required elements for every message: a severity level (ranging from DEBUG to PANIC) and a primary message text. In addition there are optional elements, the most common of which is an error identifier code that follows the SQL spec’s SQLSTATE conventions. ereport itself is just a shell macro that exists mainly for the syntactic convenience of making message generation look like a single function call in the C source code. The only parameter accepted directly by ereport is the severity level. The primary message text and any optional message elements are generated by calling auxiliary functions, such as errmsg, within the ereport call.
对 ereport 的典型调用可能是这样:
A typical call to ereport might look like this:
ereport(ERROR,
errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero"));
这指定错误严重性级别 ERROR(一个常规错误)。errcode 调用使用在 src/include/utils/errcodes.h 中定义的宏指定 SQLSTATE 错误代码。errmsg 调用提供主要消息文本。
This specifies error severity level ERROR (a run-of-the-mill error). The errcode call specifies the SQLSTATE error code using a macro defined in src/include/utils/errcodes.h. The errmsg call provides the primary message text.
你还会经常看到这种旧样式,在辅助函数调用周围有一组额外的括号:
You will also frequently see this older style, with an extra set of parentheses surrounding the auxiliary function calls:
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
在 PostgreSQL 12 版本之前需要额外的括号,但现在是可选的。
The extra parentheses were required before PostgreSQL version 12, but are now optional.
这是一个更复杂的示例:
Here is a more complex example:
ereport(ERROR,
errcode(ERRCODE_AMBIGUOUS_FUNCTION),
errmsg("function %s is not unique",
func_signature_string(funcname, nargs,
NIL, actual_arg_types)),
errhint("Unable to choose a best candidate function. "
"You might need to add explicit typecasts."));
这说明了使用格式代码将运行时值嵌入到消息文本中的用法。此外,提供了可选的“提示”消息。辅助函数调用可以按任何顺序编写,但通常 errcode 和 errmsg 会先出现。
This illustrates the use of format codes to embed run-time values into a message text. Also, an optional “hint” message is provided. The auxiliary function calls can be written in any order, but conventionally errcode and errmsg appear first.
如果严重性级别为 ERROR 或更高,ereport 将中止当前查询的执行,且不返回给调用者。如果严重性级别低于 ERROR,ereport 将正常返回。
If the severity level is ERROR or higher, ereport aborts execution of the current query and does not return to the caller. If the severity level is lower than ERROR, ereport returns normally.
ereport 可用的辅助例程有:
The available auxiliary routines for ereport are:
Note
在 ereport 调用中,最多只能使用一个 errtable、errtablecol、errtableconstraint、errdatatype 或 errdomainconstraint 函数。这些函数的存在是为了允许应用程序提取与错误条件相关联的数据库对象名称,而无需检查潜在的本地化错误消息文本。这些函数应在错误报告中使用,应用程序可能希望自动处理错误。截至 PostgreSQL 9.3,仅 SQLSTATE 类 23(完整性约束冲突)的错误有完整的覆盖,但将来可能会扩展此功能。
At most one of the functions errtable, errtablecol, errtableconstraint, errdatatype, or errdomainconstraint should be used in an ereport call. These functions exist to allow applications to extract the name of a database object associated with the error condition without having to examine the potentially-localized error message text. These functions should be used in error reports for which it’s likely that applications would wish to have automatic error handling. As of PostgreSQL 9.3, complete coverage exists only for errors in SQLSTATE class 23 (integrity constraint violation), but this is likely to be expanded in future.
有一个仍然大量使用的旧函数 elog。一个 elog 调用:
There is an older function elog that is still heavily used. An elog call:
elog(level, "format string", ...);
完全等同于:
is exactly equivalent to:
ereport(level, errmsg_internal("format string", ...));
请注意,SQLSTATE 错误代码始终为默认值,且消息字符串不受翻译。因此,elog 应该仅用于内部错误和低级调试日志记录。任何可能对普通用户有用的消息都应该通过 ereport 传递。尽管如此,系统中仍然有足够的内部“不可能发生”错误检查,从而使 elog 仍然被广泛使用;对于那些消息,它因其简记而被首选。
Notice that the SQLSTATE error code is always defaulted, and the message string is not subject to translation. Therefore, elog should be used only for internal errors and low-level debug logging. Any message that is likely to be of interest to ordinary users should go through ereport. Nonetheless, there are enough internal “cannot happen” error checks in the system that elog is still widely used; it is preferred for those messages for its notational simplicity.
有关编写良好错误消息的建议,请参见 Section 56.3。
Advice about writing good error messages can be found in Section 56.3.
[16 ] 也就是说,当 ereport 调用到达时,值是当前值;辅助报告例程中的 errno 更改不会影响该值。如果你要明确在 errmsg 的参数列表中编写 strerror(errno) ,则并非如此;因此,请勿这样做。
[16] That is, the value that was current when the ereport call was reached; changes of errno within the auxiliary reporting routines will not affect it. That would not be true if you were to write strerror(errno) explicitly in errmsg's parameter list; accordingly, do not do so.