43.2. 報告伺服器裡的錯誤

在伺服器代碼裡生成的錯誤,警告以及日誌訊息應該用 ereport,或者它的老前輩 elog 建立。 這個函數的使用已經複雜得足夠我們做些解釋了。

每條消息都有兩個必須的要素:一個嚴重級別(範圍從 DEBUGPANIC)和一個主要消息文本。 除此之外還有可選的元素,最常見的就是一個遵循 SQL 標準的 SQLSTATE 習慣的錯誤標識碼。 ereport 本身只是一個殼函數,它的存在主要是為了便於讓消息生成看起來像 C 代碼裡的函數調用。 ereport 直接接受的唯一參數是嚴重級別。 主消息文本和任何附加消息元素都是透過在 ereport 調用裡調用輔助函數,比如 errmsg,生成的。

典型的調用 ereport 的方式看起來可能像下面這樣:

ereport(ERROR,
        (errcode(ERRCODE_DIVISION_BY_ZERO),
         errmsg("division by zero")));

這樣就聲明了嚴重級別 ERROR (一個錯誤)。 調用 errcode 則使用一個定義在 src/include/utils/errcodes.h 裡面的宏聲明 SQLSTATE 錯誤代碼。 errmsg 調用提供主要的消息文本。 請注意額外的圓括弧包圍在輔助函數調用周圍 — 這麼做雖然煩人,但是語法上是必須的。

然後是一個更複雜的例子:

ereport(ERROR,
        (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
         errmsg("function %s is not unique",
                func_signature_string(funcname, nargs,
                                      actual_arg_types)),
         errhint("Unable to choose a best candidate function. "
                 "You may need to add explicit typecasts.")));

這個例子演示了使用格式化代碼把執行時數值嵌入一個消息文本的用法。 同樣,還提供了一個可選的"暗示"訊息。

ereport 可用的附屬過程有:

還有一個老一些的 elog 函數,仍然在頻繁使用。 一個 elog 調用

elog(level, "format string", ...);

完全等效於

ereport(level, (errmsg_internal("format string", ...)));

請注意 SQLSTATE 錯誤代碼總是預設的,並且消息字串並沒有包含在國際化訊息字典裡。 因此,elog 應該只用於內部錯誤以及低層的調試日誌。 任何普通用戶感興趣的消息都應該透過 ereport 生成。 當然,還有大量內部的"不可能發生"的錯誤檢查使用 elog; 因為這些訊息最好還是資料表示得簡單些好。

書寫好的錯誤消息的建議可以在 Section 43.3 找到。

Notes

[1]

也就是說,在到達 ereport 調用的時候目前的數值; 在附屬報告過程裡對 errno 的修改將不會影響他。 但是如果您在 errmsg 的參數列資料表裡明確地寫 strerror(errno), 這一點就不能保證了,因此,請不要這麼做。