Go 錯誤堆疊資訊之 CockroachDB errors 庫
目錄
1. Go 標準庫 errors 太簡單
由 fmt.Errorf() 構造的 Go 中最常見的“簡單”錯誤物件類似於帶有錯誤介面的包含在結構中的字串:其 Error() 方法返回構造錯誤時設定的字串。
// Go 標準庫 errors
// 使用 fmt.Errorf() 構造 Go 中最常見的“簡單”錯誤物件類似於帶有錯誤介面的包含在結構中的字串:列印錯誤物件只會顯示該字串。
// 使用 Go 的錯誤包 errors 的建構函式構建錯誤 errors.New() 結果一樣。
func testSimpleCustomError() {
err := fmt.Errorf("fmt.Errorf")
fmt.Println(err) // "hello"
err = errors.New("errors.New")
fmt.Println(err) // "errors.New"
}
什麼都沒有,僅此而已。列印錯誤物件也會顯示該字串。順便說一句,使用 Go 的錯誤包 errors 的建構函式構建錯誤 errors.New() 結果一樣。
2. CockroachDB錯誤處理庫
使用 Dave Cheney 的錯誤庫[1],或者甚至更好的 CockroachDB 錯誤庫[2](通過導github.com/cockroachdb/errors),則簡單錯誤也會在構造錯誤時自動捕獲堆疊跟蹤。僅當詳細列印錯誤時才顯示堆疊跟蹤。這樣可以更輕鬆地排除錯誤的來源:
2.1 CockroachDB 新建堆疊錯誤
使用 Dave Cheney 的錯誤庫[1],或者甚至更好的 CockroachDB 錯誤庫[2](通過匯入 ithub.com/cockroachdb/errors)則簡單錯誤也會在構造錯誤時自動捕獲堆疊跟蹤。
建議使用CockroachDB庫的以下方法代替GO的標準錯誤處理庫:
errors.New():直接替換 Go 標準庫的 errors.New(),但它會帶有堆疊跟蹤;
errors.Errorf() 或 errors.Newf():用堆疊跟蹤的方式替換 Go 標準庫的 fmt.Errorf();
func testCockroachdbError() {
err := cockroachdb_errors.New("cockroachdb_errors.New")
fmt.Println("只會顯示錯誤字串:", err)
fmt.Println("顯示錯誤堆疊資訊:", err)
fmt.Printf("%+v \n", err) // 推薦
}
2.2 CockroachDB 新增錯誤上下文字首
當從多個位置呼叫相同的邏輯,並且可能因錯誤而失敗時,則希望將訊息字首新增到任何返回的錯誤物件。
這有助於提供有關“錯誤發生的位置”的更多上下文,以便在執行時出現錯誤時(何時出現錯誤),可以清楚地瞭解哪個程式碼路徑產生了錯誤。
在 channel 的場景出現錯誤是特別有用。
func foo() error { return errors.New("boo") }
func bar() error {
if err := foo(); err != nil {
return cockroachdb_errors.Wrap(err, "bar")
}
return nil
}
func baz() error {
// 當提供 nil 錯誤作為輸入時,errors.Wrap() 返回nil。這使我們可以消除 if err != nil 條件。
return cockroachdb_errors.Wrap(foo(), "baz")
}
func testCockroachdbErrorWrap() {
err1 := bar()
fmt.Printf("%+v \n", err1)
err2 := baz()
fmt.Printf("%+v \n", err2)
}
1.3. CockroachDB 次要錯誤
如果在處理錯誤時遇到錯誤,該怎麼辦?
我們希望以某種方式返回有關這兩個錯誤的詳細資訊,以幫助進行故障排除。
同時,出於原因分析的目的,我們要謹慎地將遇到的第一個錯誤保留為 “主要” 錯誤。
次要錯誤註解不會影響主要錯誤上返回的文字,程式碼的行為就像僅發生了主要錯誤一樣。但是,在詳細列印過程中會顯示第二個錯誤的資訊;
func testCockroachdbSecondaryError() {
err := errors.New("主要錯誤")
err = cockroachdb_errors.Wrap(err, "主要資訊字首")
err = cockroachdb_errors.WithSecondaryError(err, cockroachdb_errors.New("次要錯誤"))
fmt.Println(err) // 只列印 "主要錯誤"
fmt.Printf("%+v \n", err) // 列印只要錯誤和次要錯誤的堆疊資訊
}
總結
Go 庫通過 Go 自己的錯誤包中的 fmt.Errorf() 和 errors.New() 提供了錯誤介面的簡化實現。
改用 CockroachDB 錯誤庫,代替 Go 的錯誤包和 Dave Cheney的 pkg/errors,可以獲得更好的體驗。
它的錯誤建構函式 errors.New()/errors.Newf()(別名為 errors.Errorf())自動在錯誤物件中包含堆疊跟蹤,可以使用 fmt.Printf("%+v" ,err) 列印堆疊追蹤。
它還提供了錯誤包裝器的詞彙表。最常見的是帶有 errors.Wrap()/errors.Wrapf() 的訊息字首註釋,用於註釋從多個位置呼叫的函式的呼叫路徑。這還包括幕後的堆疊跟蹤。
另一個常見的包裝器解決了在處理另一個錯誤時遇到錯誤時如何在 Go 中執行的令人困惑的問題:使用輔助原因註解,並使用 errors.WithSecondaryCause() 或 errors.CombineErrors() 附加,Go 程式碼可以保留兩個錯誤,因此程式設計師在故障排除期間可以同時看到兩者。
CockroachDB 錯誤庫中的錯誤還提供了一致的行為,並且在詳細格式化錯誤時提供了有用的顯示結構,從而避免了巨大的 Go 錯誤列印災難。
筆記原始碼: https://github.com/qiuyunzhao/go_basis/blob/master/12_%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86/02_%E8%87%AA%E5%AE%9A%E4%B9%89%E9%94%99%E8%AF%AF%26%E9%94%99%E8%AF%AF%E5%A0%86%E6%A0%88/main.go
相關文章
- 使用Error Stack跟蹤Oracle錯誤堆疊資訊ErrorOracle
- 通過錯誤堆疊資訊和原始碼分析錯誤來源原始碼
- StackOverflowError堆疊溢位錯誤Error
- Laravel/Lumen 自定義錯誤日誌格式過濾堆疊資訊Laravel
- [譯] Go 1.13 errors 包錯誤處理GoError
- 【原創】mysql 錯誤緩衝堆疊薦MySql
- 如何優雅地檢視 JS 錯誤堆疊?JS
- 利用Decorator和SourceMap優化JavaScript錯誤堆疊優化JavaScript
- 深入理解 JavaScript 錯誤和堆疊追蹤JavaScript
- GOLANG測試必須用帶堆疊的errorsGolangError
- JavaScript 錯誤處理和堆疊追蹤淺析JavaScript
- thinkphp console 命令列列印錯誤呼叫堆疊PHP命令列
- android I/DEBUG堆疊資訊Android
- 監控Java層和JNI Native層Crash,分析.so庫報錯的堆疊資訊Java
- android 解碼混淆過的堆疊資訊Android
- Java獲取堆疊資訊的3種方法Java
- CSS之定位和堆疊屬性CSS
- JS 堆疊JS
- java堆疊Java
- 堆疊圖
- 平衡堆疊
- 堆疊溢位報錯引發的思考
- JVM異常不列印堆疊資訊 [ -XX:-OmitStackTraceInFastThrow ]JVMMITAST
- 開心檔之Go 錯誤處理Go
- pretty-printers:更優雅的看GDB堆疊資訊
- Flask_restful 之 自定義錯誤資訊FlaskREST
- 初探堆疊欺騙之靜態欺騙
- Go Errors 詳解GoError
- 圖的深度優先遍歷[非堆疊、堆疊實現]
- 與 AI 互動 - 學習如何看呼叫鏈堆疊資訊AI
- 記憶體堆疊記憶體
- 堆疊的工作原理
- C#堆疊(Stack)C#
- 理解ASP.NET Core - 錯誤處理(Handle Errors)ASP.NETError
- JavaScript錯誤資訊JavaScript
- sql注入之堆疊注入及waf繞過注入SQL
- Android學習之 Activity堆疊管理與控制Android
- 再探堆疊欺騙之動態欺騙