
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` 技能。
符合 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 應用程式中建立穩健且符合慣例的錯誤處理。遵循這些原則以撰寫可維護、可除錯且適用於生產環境的錯誤程式碼。
最佳實踐摘要
- 回傳的錯誤 MUST 永遠被檢查 — 絕不使用
_丟棄 - 錯誤 MUST 使用上下文包裝,使用
fmt.Errorf("{context}: %w", err) - 錯誤字串 MUST 為小寫,且不含結尾標點符號
- 內部使用
%w,系統邊界使用%v以控制錯誤鏈的暴露 - MUST 使用
errors.Is進行哨兵比對,使用errors.As/errors.AsType進行型別鏈檢查,而非直接比較或裸型別斷言。對於 Go 1.26+,當T實作error時,優先使用errors.AsType[T](err);對於 Go <1.26 或非 error 介面目標,使用errors.As(err, &target)。 - SHOULD 使用
errors.Join(Go 1.20+)來合併獨立錯誤 - 錯誤 MUST 要麼被記錄,要麼被回傳,絕不能兩者都做(單一處理原則)
- 對預期條件使用哨兵錯誤,對攜帶資料使用自訂型別
- 絕不使用
panic處理預期的錯誤條件 — 保留給真正不可復原的狀態 - SHOULD 使用
slog(Go 1.21+)進行結構化錯誤記錄 — 而非fmt.Println或log.Printf - 對需要堆疊追蹤、使用者/租戶上下文或結構化屬性的生產環境錯誤,使用
samber/oops - 使用結構化中介軟體記錄 HTTP 請求,捕捉方法、路徑、狀態碼和持續時間
- 使用日誌層級 指示錯誤嚴重性
- 絕不向使用者暴露技術錯誤 — 將內部錯誤轉換為使用者友善訊息,技術細節另外記錄
- 保持日誌分組的低基數 — 在記錄/APM 邊界,保持訊息模板穩定,並將 ID、路徑、行號和計數作為結構化屬性附加。錯誤值可能包含有用的操作上下文,但避免將高基數資料放入用於分組的穩定日誌訊息中。
詳細參考
-
錯誤建立 — 如何建立能講述故事的錯誤:錯誤訊息應為小寫、無標點符號,並描述發生的事情而不指定動作。涵蓋哨兵錯誤(一次性預分配以提升效能)、自訂錯誤型別(用於攜帶豐富上下文),以及何時使用哪一種的決策表。
-
錯誤包裝與檢查 — 為什麼
fmt.Errorf("{context}: %w", err)優於fmt.Errorf("{context}: %v", err)(鏈結 vs 串接)。如何使用errors.Is、errors.As以及 Go 1.26+ 的errors.AsType進行型別安全的錯誤處理來檢查鏈結,以及使用errors.Join合併獨立錯誤。 -
錯誤處理模式與記錄 — 單一處理原則:錯誤要麼被記錄,要麼被回傳,絕不能兩者都做(防止重複記錄造成聚合器混亂)。Panic/recover 設計、用於生產環境錯誤的
samber/oops,以及與 APM 工具整合的slog結構化記錄。
並行化錯誤處理稽核
在大型程式碼庫中稽核錯誤處理時,最多使用 5 個並行子代理(透過 Agent 工具)— 每個針對一個獨立的錯誤類別:
- 子代理 1:錯誤建立 — 驗證
errors.New/fmt.Errorf的使用、低基數訊息、自訂型別 - 子代理 2:錯誤包裝 — 稽核
%wvs%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 驅動的程式碼審查





