Go語言中實現(xiàn)打印堆棧的errors包的用法詳解
Go語言打印堆棧errors包
因為Go語言提供的錯誤太簡單了,以至于簡單的我們無法更好的處理問題,甚至不能為我們處理錯誤,提供更有用的信息,所以誕生了很多對錯誤處理的庫,github.com/pkg/errors是比較簡潔的一樣,并且功能非常強(qiáng)大,受到了大量開發(fā)者的歡迎,使用者很多。
1、安裝
go get github.com/pkg/errors
2、使用
跟蹤堆棧信息的函數(shù)使用:
// 新生成一個錯誤, 帶堆棧信息 func New(message string) error //只附加新的信息 func WithMessage(err error, message string) error //只附加調(diào)用堆棧信息 func WithStack(err error) error //同時附加堆棧和信息 func Wrap(err error, message string) error
打印出堆棧信息:
// 功能一樣,輸出錯誤信息,不包含堆棧 %s,%v // 輸出的錯誤信息帶引號,不包含堆棧 %q // 輸出錯誤信息和堆棧 %+v //如: fmt.Println(fmt.Sprintf("%s", err)) fmt.Println(fmt.Sprintf("%q", err)) fmt.Println(fmt.Sprintf("%+v", err))
2.1 New()函數(shù)
它的使用非常簡單,如果我們要新生成一個錯誤,可以使用 New 函數(shù)生成錯誤,自帶調(diào)用堆棧信息。
// 例子 package main import ( "fmt" "github.com/pkg/errors" ) func main() { result, err := Divide(10, 0) if err != nil { fmt.Println(fmt.Sprintf("error1: %v", err)) fmt.Println(fmt.Sprintf("error2: %s", err)) fmt.Println(fmt.Sprintf("error3: %q", err)) fmt.Println(fmt.Sprintf("error4: %+v", err)) } else { fmt.Println("result:", result) } } func Divide(a, b int) (int, error) { if b == 0 { return 0, errors.New("division can not 0") } else { return a / b, nil } }
程序輸出
error1: division can not 0
error2: division can not 0
error3: "division can not 0"
error4: division can not 0
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/001.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/001.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
如果有一個現(xiàn)成的 error,我們需要對他進(jìn)行再次包裝處理,這時候有三個函數(shù)可以選擇。
//只附加新的信息 func WithMessage(err error, message string) error //只附加調(diào)用堆棧信息 func WithStack(err error) error //同時附加堆棧和信息 func Wrap(err error, message string) error
2.2 WithMessage()函數(shù)
// 例子 package main import ( "fmt" "github.com/pkg/errors" ) func main() { result, err := Divide(10, 0) if err != nil { fmt.Println(fmt.Sprintf("error1: %v", err)) fmt.Println(fmt.Sprintf("error2: %s", err)) fmt.Println(fmt.Sprintf("error3: %q", err)) fmt.Println(fmt.Sprintf("error4: %+v", err)) } else { fmt.Println("result:", result) } } func Divide(a, b int) (int, error) { if b == 0 { return 0, errors.WithMessage(errors.New("division can not 0"),"func Divide(a, b int) (int, error) {}") } else { return a / b, nil } }
程序輸出
error1: func Divide(a, b int) (int, error) {}: division can not 0
error2: func Divide(a, b int) (int, error) {}: division can not 0
error3: func Divide(a, b int) (int, error) {}: division can not 0
error4: division can not 0
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/002.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/002.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
func Divide(a, b int) (int, error) {}
2.3 WithStack()
// 例子 package main import ( "fmt" "github.com/pkg/errors" ) func main() { result, err := Divide(10, 0) if err != nil { fmt.Println(fmt.Sprintf("error1: %v", err)) fmt.Println(fmt.Sprintf("error2: %s", err)) fmt.Println(fmt.Sprintf("error3: %q", err)) fmt.Println(fmt.Sprintf("error4: %+v", err)) } else { fmt.Println("result:", result) } } func Divide(a, b int) (int, error) { if b == 0 { return 0, errors.WithStack(errors.New("division can not 0")) } else { return a / b, nil } }
程序輸出
error1: division can not 0
error2: division can not 0
error3: "division can not 0"
error4: division can not 0
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/003.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/003.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/003.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/003.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
2.4 Wrap()函數(shù)
// 例子 package main import ( "fmt" "github.com/pkg/errors" ) func main() { result, err := Divide(10, 0) if err != nil { fmt.Println(fmt.Sprintf("error1: %v", err)) fmt.Println(fmt.Sprintf("error2: %s", err)) fmt.Println(fmt.Sprintf("error3: %q", err)) fmt.Println(fmt.Sprintf("error4: %+v", err)) } else { fmt.Println("result:", result) } } func Divide(a, b int) (int, error) { if b == 0 { return 0, errors.Wrap(errors.New("division can not 0"),"func Divide(a, b int) (int, error){}") } else { return a / b, nil } }
程序輸出
error1: func Divide(a, b int) (int, error){}: division can not 0
error2: func Divide(a, b int) (int, error){}: division can not 0
error3: "func Divide(a, b int) (int, error){}: division can not 0"
error4: division can not 0
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/004.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/004.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
func Divide(a, b int) (int, error){}
main.Divide
C:/Users/admin/Desktop/gg/new/go-errors/004.go:23
main.main
C:/Users/admin/Desktop/gg/new/go-errors/004.go:10
runtime.main
D:/install/go1.18.4/src/runtime/proc.go:250
runtime.goexit
D:/install/go1.18.4/src/runtime/asm_amd64.s:1571
這里只是簡單介紹相關(guān)函數(shù)的使用,我們可以自己對這些函數(shù)進(jìn)行封裝,然后在相應(yīng)的地方進(jìn)行調(diào)用。
3、總結(jié)
通過使用這個 github.com/pkg/errors 錯誤庫,我們可以收集更多的信息,可以讓我們更容易的定位問題。
我們收集的這些信息不止可以輸出到控制臺,也可以當(dāng)做日志,使用輸出到相應(yīng)的 Log 日志里,便于分析問題。
以上就是Go語言中實現(xiàn)打印堆棧的errors包的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于Go語言打印堆棧errors包的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang使用Channel組建高并發(fā)HTTP服務(wù)器
Golang 作為一門高效的語言,在網(wǎng)絡(luò)編程方面表現(xiàn)也非常出色,這篇文章主要介紹了如何使用 Golang 和 Channel 組建高并發(fā) HTTP 服務(wù)器,感興趣的可以了解一下2023-06-06成功安裝vscode中g(shù)o的相關(guān)插件(詳細(xì)教程)
這篇文章主要介紹了成功安裝vscode中g(shù)o的相關(guān)插件的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05Prometheus Go client library使用方式詳解
這篇文章主要為大家介紹了Prometheus Go client library使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11go程序測試CPU占用率統(tǒng)計ps?vs?top兩種不同方式對比
這篇文章主要為大家介紹了go程序測試CPU占用率統(tǒng)計ps?vs?top兩種不同方式對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05golang 實現(xiàn)時間戳和時間的轉(zhuǎn)化
這篇文章主要介紹了golang 實現(xiàn)時間戳和時間的轉(zhuǎn)化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05