本風格指南旨在為 PostgreSQL 生成的所有訊息提供一種一致的、對使用者友好的風格。
主訊息應簡短、客觀,並避擴音及實現細節,如特定的函式名。“簡短”意味著“在正常情況下應能顯示在一行內”。如果需要,可以使用詳細訊息來保持主訊息的簡短,或者當需要提及實現細節(例如失敗的具體系統呼叫)時。主訊息和詳細訊息都應客觀。提示訊息可用於提供解決問題的建議,尤其是當建議不總是適用時。
例如,而不是
IpcMemoryCreate: shmget(key=%d, size=%u, 0%o) failed: %m (plus a long addendum that is basically a hint)
寫入
Primary: could not create shared memory segment: %m Detail: Failed syscall was shmget(key=%d, size=%u, 0%o). Hint: The addendum, written as a complete sentence.
理由:保持主訊息簡短有助於使其切題,並允許客戶端應用程式根據假設一行足以顯示錯誤訊息來佈局螢幕空間。詳細訊息和提示訊息可以被隱藏在冗長模式下,或者可能是一個彈出式錯誤詳細資訊視窗。此外,詳細資訊和提示通常會從伺服器日誌中隱藏以節省空間。最好避擴音及實現細節,因為使用者不需要了解這些細節。
不要在訊息文字中加入任何關於格式的具體假設。假定客戶端和伺服器日誌會根據自己的需求進行換行。在長訊息中,可以使用換行符(\n)來指示建議的段落分隔。不要在訊息末尾新增換行符。不要使用製表符或其他格式化字元。(在錯誤上下文顯示中,會自動新增換行符來分隔上下文級別,如函式呼叫。)
理由:訊息不一定顯示在終端型別的顯示器上。在 GUI 顯示或瀏覽器中,這些格式化指令充其量會被忽略。
英文文字在需要引用時應使用雙引號。其他語言的文字應始終使用一種與出版習俗和程式計算機輸出一致的引號。
理由:選擇雙引號而不是單引號在某種程度上是隨意的,但往往是首選用法。有人建議根據 SQL 約定(即字串用單引號,識別符號用雙引號)來選擇引號的型別。但這是一個語言內部的技術問題,許多使用者甚至不熟悉,它無法擴充套件到其他型別的引用術語,它無法翻譯成其他語言,而且相當沒有意義。
始終使用引號來分隔檔名、使用者提供的識別符號、配置檔案變數名以及其他可能包含單詞的變數。不要用引號來標記不包含單詞的變數(例如,運算子名稱)。
後端有一些函式會根據需要自動對輸出進行雙引號處理(例如,format_type_be()
)。不要對這些函式的輸出新增額外的引號。
理由:物件可能具有在訊息中嵌入時會產生歧義的名稱。在標記插入名稱的開始和結束位置時要保持一致。但不要在訊息中新增不必要或重複的引號。
主錯誤訊息和詳細/提示訊息的規則不同
主錯誤訊息:不要大寫首字母。不要在訊息末尾加句號。不要考慮在訊息末尾加感嘆號。
詳細訊息和提示訊息:使用完整的句子,並在每個句子末尾加句號。大寫句子的第一個單詞。句號後加兩個空格(如果是英文文字;在其他語言中可能不合適)。
錯誤上下文字串:不要大寫首字母,也不要在字串末尾加句號。上下文字串通常不應是完整的句子。
理由:避免標點符號可以幫助客戶端應用程式將訊息嵌入到各種語法上下文中。通常,主訊息本來就不是完整的句子。(如果它們足夠長,包含多個句子,則應將其拆分為主部分和詳細部分。)然而,詳細訊息和提示訊息較長,可能需要包含多個句子。為了保持一致性,即使只有一個句子,它們也應遵循完整句子的風格。
如果嘗試某事失敗,但下次可能成功(也許在修復某些問題後),則使用過去時。如果失敗肯定永久存在,則使用現在時。
以下形式的句子之間存在細微的語義差異:
could not open file "%s": %m
和
cannot open file "%s"
第一種形式表示開啟檔案的嘗試失敗了。訊息應給出原因,例如“磁碟已滿”或“檔案不存在”。過去時是合適的,因為下次磁碟可能不再滿,或者檔案可能存在。
第二種形式表示程式中根本不存在開啟命名檔案的功能,或者在概念上是不可能的。現在時是合適的,因為這種情況將無限期地持續下去。
理由:誠然,普通使用者無法僅從訊息的時態中得出太多結論,但由於語言為我們提供了語法,我們應該正確使用它。
當訊息包含來自其他地方生成的文字時,請按此風格嵌入:
could not open file %s: %m
理由:很難考慮到所有可能的錯誤程式碼來將此內容貼上成一個流暢的句子,因此需要某種標點符號。也有人建議將嵌入的文字放在括號中,但這並不自然,因為嵌入的文字通常是訊息中最重要的一部分,這種情況很常見。
訊息應始終說明錯誤發生的原因。例如:
BAD: could not open file %s BETTER: could not open file %s (I/O failure)
如果原因不明,最好修復程式碼。
不要在錯誤文字中包含報告例程的名稱。我們有其他機制可以在需要時找出這些資訊,而對於大多數使用者來說,這不是有用的資訊。如果錯誤文字在沒有函式名的情況下不太有意義,請重新措辭。
BAD: pg_strtoint32: error in "z": cannot parse "z" BETTER: invalid input syntax for type integer: "z"
也要避擴音及被呼叫的函式名;而是說明程式碼試圖做什麼
BAD: open() failed: %m BETTER: could not open file %s: %m
如果確實有必要,請在詳細訊息中提及系統呼叫。(在某些情況下,提供傳遞給系統呼叫的實際值可能適合作為詳細訊息的資訊。)
理由:使用者不知道所有這些函式的功能。
無法(Unable)。 “無法”近乎被動語態。最好使用“不能(cannot)”或“不能(could not)”,視情況而定。
錯誤(Bad)。 像“錯誤的結果”這樣的錯誤訊息很難被智慧地解釋。最好寫出為什麼結果是“錯誤”的,例如,“格式無效”。
非法(Illegal)。 “非法”表示違反法律,其他則是“無效”。更好的是,說明為什麼它是無效的。
未知(Unknown)。 儘量避免使用“未知”。考慮“錯誤:未知響應”。如果你不知道響應是什麼,你怎麼知道它是錯誤的?“無法識別(Unrecognized)”通常是更好的選擇。另外,請務必包含被抱怨的值。
BAD: unknown node type BETTER: unrecognized node type: 42
查詢 vs. 存在(Find vs. Exists)。 如果程式使用非平凡的演算法來定位資源(例如,路徑搜尋)並且該演算法失敗,那麼說程式無法“找到”資源是可以的。另一方面,如果已知資源的預期位置但程式無法訪問,則說資源“不存在”。在這種情況下使用“找到”聽起來很弱,並混淆了問題。
可能(May) vs. 能夠(Can) vs. 也許(Might)。 “May”暗示許可(例如,“你可以借我的耙子。”),在文件或錯誤訊息中很少使用。“Can”暗示能力(例如,“我可以舉起那個原木。”),而“Might”暗示可能性(例如,“今天可能會下雨。”)。使用正確的詞語可以澄清含義並輔助翻譯。
縮寫。 避免使用縮寫,如“不能(can't)”;而是使用“不能(cannot)”。
非負(Non-negative)。 避免使用“非負”,因為它含糊不清,不確定是否接受零。最好使用“大於零”或“大於或等於零”。
如果您在文件中看到任何不正確、與您對特定功能的經驗不符或需要進一步說明的內容,請使用 此表單 報告文件問題。