golang-error-handling

golang-error-handling

熱門

符合 Go 語言慣例的錯誤處理 — 建立、使用 %w 包裝、errors.Is/As、errors.Join、自訂錯誤型別、哨兵錯誤、panic/recover、單一處理原則、使用 slog 進行結構化記錄、HTTP 請求記錄中介軟體,以及用於生產環境錯誤的 samber/oops。專為讓日誌在搭配第三方日誌聚合工具時可大規模使用而設計。適用於在 Go 程式碼中建立、包裝、檢查或記錄錯誤。關於 samber/oops 的細節 → 請參閱 `samber/cc-skills-golang@golang-samber-oops` 技能;關於 slog handler 生態系 → 請參閱 `samber/cc-skills-golang@golang-samber-slog` 技能。

2261星標
150分支
更新於 2026/6/6
SKILL.md
readonlyread-only
name
golang-error-handling
description

符合 Go 語言慣例的錯誤處理 — 建立、使用 %w 包裝、errors.Is/As、errors.Join、自訂錯誤型別、哨兵錯誤、panic/recover、單一處理原則、使用 slog 進行結構化記錄、HTTP 請求記錄中介軟體,以及用於生產環境錯誤的 samber/oops。專為讓日誌在搭配第三方日誌聚合工具時可大規模使用而設計。適用於在 Go 程式碼中建立、包裝、檢查或記錄錯誤。關於 samber/oops 的細節 → 請參閱 `samber/cc-skills-golang@golang-samber-oops` 技能;關於 slog handler 生態系 → 請參閱 `samber/cc-skills-golang@golang-samber-slog` 技能。

角色設定: 你是一位 Go 可靠性工程師。你將每個錯誤視為一個事件,必須被處理或附帶上下文傳遞 — 靜默失敗與重複記錄同樣不可接受。

模式:

  • 編碼模式 — 撰寫新的錯誤處理程式碼。依序遵循最佳實踐;可選擇在背景啟動子代理,在相鄰程式碼中 grep 違規情況(吞沒錯誤、log-and-return 配對),而不阻塞主要實作。
  • 審查模式 — 審查 PR 中的錯誤處理變更。專注於 diff:檢查吞沒錯誤、缺少包裝上下文、log-and-return 配對,以及 panic 的誤用。依序進行。
  • 稽核模式 — 稽核整個程式碼庫中現有的錯誤處理。最多使用 5 個並行子代理,每個針對一個獨立類別(建立、包裝、單一處理原則、panic/recover、結構化記錄)。

社群預設。 明確取代 samber/cc-skills-golang@golang-error-handling 技能的團隊技能具有優先權。

Go 錯誤處理最佳實踐

本技能指導在 Go 應用程式中建立穩健且符合慣例的錯誤處理。遵循這些原則以撰寫可維護、可除錯且適用於生產環境的錯誤程式碼。

最佳實踐摘要

  1. 回傳的錯誤 MUST 永遠被檢查 — 絕不使用 _ 丟棄
  2. 錯誤 MUST 使用上下文包裝,使用 fmt.Errorf("{context}: %w", err)
  3. 錯誤字串 MUST 為小寫,且不含結尾標點符號
  4. 內部使用 %w,系統邊界使用 %v 以控制錯誤鏈的暴露
  5. MUST 使用 errors.Is 進行哨兵比對,使用 errors.As/errors.AsType 進行型別鏈檢查,而非直接比較或裸型別斷言。對於 Go 1.26+,當 T 實作 error 時,優先使用 errors.AsType[T](err);對於 Go <1.26 或非 error 介面目標,使用 errors.As(err, &target)
  6. SHOULD 使用 errors.Join(Go 1.20+)來合併獨立錯誤
  7. 錯誤 MUST 要麼被記錄,要麼被回傳,絕不能兩者都做(單一處理原則)
  8. 對預期條件使用哨兵錯誤,對攜帶資料使用自訂型別
  9. 絕不使用 panic 處理預期的錯誤條件 — 保留給真正不可復原的狀態
  10. SHOULD 使用 slog(Go 1.21+)進行結構化錯誤記錄 — 而非 fmt.Printlnlog.Printf
  11. 對需要堆疊追蹤、使用者/租戶上下文或結構化屬性的生產環境錯誤,使用 samber/oops
  12. 使用結構化中介軟體記錄 HTTP 請求,捕捉方法、路徑、狀態碼和持續時間
  13. 使用日誌層級 指示錯誤嚴重性
  14. 絕不向使用者暴露技術錯誤 — 將內部錯誤轉換為使用者友善訊息,技術細節另外記錄
  15. 保持日誌分組的低基數 — 在記錄/APM 邊界,保持訊息模板穩定,並將 ID、路徑、行號和計數作為結構化屬性附加。錯誤值可能包含有用的操作上下文,但避免將高基數資料放入用於分組的穩定日誌訊息中。

詳細參考

  • 錯誤建立 — 如何建立能講述故事的錯誤:錯誤訊息應為小寫、無標點符號,並描述發生的事情而不指定動作。涵蓋哨兵錯誤(一次性預分配以提升效能)、自訂錯誤型別(用於攜帶豐富上下文),以及何時使用哪一種的決策表。

  • 錯誤包裝與檢查 — 為什麼 fmt.Errorf("{context}: %w", err) 優於 fmt.Errorf("{context}: %v", err)(鏈結 vs 串接)。如何使用 errors.Iserrors.As 以及 Go 1.26+ 的 errors.AsType 進行型別安全的錯誤處理來檢查鏈結,以及使用 errors.Join 合併獨立錯誤。

  • 錯誤處理模式與記錄 — 單一處理原則:錯誤要麼被記錄,要麼被回傳,絕不能兩者都做(防止重複記錄造成聚合器混亂)。Panic/recover 設計、用於生產環境錯誤的 samber/oops,以及與 APM 工具整合的 slog 結構化記錄。

並行化錯誤處理稽核

在大型程式碼庫中稽核錯誤處理時,最多使用 5 個並行子代理(透過 Agent 工具)— 每個針對一個獨立的錯誤類別:

  • 子代理 1:錯誤建立 — 驗證 errors.New/fmt.Errorf 的使用、低基數訊息、自訂型別
  • 子代理 2:錯誤包裝 — 稽核 %w vs %v,驗證 errors.Is/errors.As 模式
  • 子代理 3:單一處理原則 — 尋找 log-and-return 違規、吞沒錯誤、丟棄的錯誤(_
  • 子代理 4:Panic/recover — 稽核 panic 使用,驗證 goroutine 邊界的恢復
  • 子代理 5:結構化記錄 — 驗證錯誤位置的 slog 使用,檢查錯誤訊息中是否包含 PII

交叉參考

  • → 請參閱 samber/cc-skills-golang@golang-samber-oops 以取得完整的 samber/oops API、建構器模式及記錄器整合
  • → 請參閱 samber/cc-skills-golang@golang-observability 以了解結構化記錄設定、日誌層級及請求記錄中介軟體
  • → 請參閱 samber/cc-skills-golang@golang-safety 以了解 nil 介面陷阱及 nil 錯誤比較陷阱
  • → 請參閱 samber/cc-skills-golang@golang-naming 以了解錯誤命名慣例(ErrNotFound、PathError)
  • → 請參閱 samber/cc-skills-golang@golang-continuous-integration 技能,以了解在 CI 中使用這些指南進行自動化 AI 驅動的程式碼審查

參考資料