元件管理員錯誤樣式指南

提振精神

所有錯誤的上方應該都很實用。這是他們唯一的存在 否則我們會認為失敗,讓所有人都知道發生了什麼事。

錯誤應提供使用者需要採取適當行動的相關資訊。使用者有時會成為程式碼中的 match,有時也會是查看記錄緩衝區的人類。想為他們提供實用的內容 就必須顧及他們的需求

您只要遵守以下原則即可:

  • 錯誤會變得更有意義
  • 錯誤更容易處理
  • 元件管理員的程式碼集更容易讀取
  • 這些錯誤將避免更多錯誤
  • 會更容易修正觸發錯誤的錯誤

原則

下列原則只是準則 (儘管遠大的原則),說明如何製作有意義的實用錯誤。如果您認為這些規範在某種程度上有誤,請善用您的判斷力,更新這份文件。

請勿謹慎使用 panic!assert!unwrap(...)expect(...)

元件管理員不應當機。如果元件管理員當機,系統會重新啟動,使用者資料可能會遺失。

極少數情況下可發生當機情形:

請勿使用 println!

雖然 println! 與元件管理員中的 debuglog 整合,但 tracing log library 提供更多功能,且廣泛用於程式碼集。tracing 程式庫也會與偵錯記錄檔整合,提供便利的巨集,並支援結構化記錄。

這項操作目前受到 Lint 規則保護。

請勿使用 anyhow 程式庫

透過 anyhow 程式庫,您無法建構結構良好的錯誤類型並加以比對。

這項規則沒有任何已知的例外狀況。

使用 thiserror 程式庫建立自訂錯誤類型

thiserror 程式庫會自動針對自訂錯誤類型自動實作 std::error::Error。避免手動實作 std::error::Error

這項規則沒有任何已知的例外狀況。

在元件管理服務中為特定功能/動作建立自訂錯誤類型

自訂錯誤類型有助於列舉功能/動作的所有可能錯誤狀態。不會與元件管理員的其他區域綁定,且可獨立於程式碼集的其餘部分進行維護。

考量是否需要為自訂錯誤類型導入 Into<ModelError>

ModelError 有許多不同錯誤類別的列舉變化版本。您不需要將自訂錯誤類型新增到 ModelError。

請勿ModelError 中加入精確錯誤

最好建立自訂錯誤類型來代表功能/動作的所有錯誤,就算您目前只有一個錯誤也一樣。如果直接將精確錯誤新增至 ModelError,開發人員可能會失去錯誤適用範圍的背景資訊。

請勿儲存 CloneableError 等一般錯誤類型

一般錯誤類型無法建構結構良好的錯誤。這些泛型類型沒有慣用的比對方式。

這項規則的唯一例外狀況,是錯誤來自使用一般錯誤類型的外部程式庫。可能無法變更外部程式庫,因此可以儲存一般程式庫。

請勿將現有錯誤類型用於「夠近」的行為

元件管理員中造成根本原因的錯誤時,如錯誤描述世界狀態的錯誤,將導致系統難以偵錯,尤其是在元件管理員中。建議您建立錯誤類型,以精確描述不同的錯誤狀態。另一個選項是在現有錯誤類型中新增列舉,以提供額外分類。

這項規則沒有任何已知的例外狀況。

務必考量是否一定要記錄記錄功能

您可以將元件管理員想成一種是多元化的超程式庫。程式庫通常是由元件管理員「無法」得知錯誤是否具有意義。舉例來說,如果 UDP 程式庫為每個捨棄的封包記錄了記錄,就會發生什麼情況。

雖然目前沒有通用的建議,但元件管理員仍有一些注意事項:

  • 使用記錄功能時保持保守。
  • 如果記錄是為了協助開發/偵錯而建立,就必須先移除這些記錄,或設為 DEBUG 記錄層級才能提交。
  • 請避免在熱程式碼路徑中新增記錄。這可能會產生垃圾記錄和垃圾內容。
  • 如果 FIDL 也傳回錯誤給用戶端,且詳細資料數量相同,則不要記錄該錯誤。
  • 反之,如果在透過 FIDL 傳送錯誤時遺失了某些細節,則可以記錄詳細的錯誤訊息。
    • 此外,也請考慮客戶未收到詳細錯誤的原因。
  • 記錄未涉及用戶端的錯誤,且該項錯誤可能對問題偵錯十分重要。
  • 遵循 RFC-0003 中設定的記錄準則

務必在記錄和錯誤中新增元件 ID

元件管理員通常會產生與特定元件相關的錯誤。確認錯誤包含元件 ID,方便偵錯。如果是記錄,請使用元件範圍記錄器,或在訊息中加入元件 ID。

可接受的元件 ID (依偏好順序排序):車輛、元件網址、執行個體 ID

請勿列印記錄訊息中的 Debug 物件字串

Debug 特徵和對應的 {:?} 格式指定碼只應用於互動式偵錯。將對等的 JSON 物件輸出到記錄中,會讓物件更難理解。最好將使用者可理解的錯誤訊息列印到記錄中。

這項規則沒有任何已知的例外狀況。

「請勿」儲存字串化的錯誤訊息

請勿儲存錯誤的 DebugDisplay 字串。字串錯誤沒有可靠的結構,而且無法進行比對。請一律依原樣儲存錯誤。

外部程式庫中的部分錯誤不會實作 ClonePartialEq 等必要的特徵。在這種罕見情況中,如果無法將這些特徵加入外部程式庫,您可以改為將錯誤訊息字串字串,並改為儲存。

請勿為每個錯誤變化版本建立函式

錯誤變數的建立函式不需要使用。可讓您對部分類型的隱含轉換進行隱含轉換,同時隱藏欄位名稱。想要直接建立錯誤類型並手動設定欄位名稱。

這項規則沒有任何已知的例外狀況。

思考如何稱霸戰士

元件管理員是一個大型 Crate。我們已將轉送功能移至各自的 Crate,日後可能會執行更多工作。如果您正在處理的特定程式碼部分是專屬 Crate 的一部分,請考慮使用哪種錯誤類型。針對 crate 中的邏輯集合,這屬於合理的錯誤類型?