Go語言中實現(xiàn)打印堆棧的errors包的用法詳解
Go語言打印堆棧errors包
因為Go語言提供的錯誤太簡單了,以至于簡單的我們無法更好的處理問題,甚至不能為我們處理錯誤,提供更有用的信息,所以誕生了很多對錯誤處理的庫,github.com/pkg/errors是比較簡潔的一樣,并且功能非常強大,受到了大量開發(fā)者的歡迎,使用者很多。
1、安裝
go get github.com/pkg/errors
2、使用
跟蹤堆棧信息的函數(shù)使用:
// 新生成一個錯誤, 帶堆棧信息 func New(message string) error //只附加新的信息 func WithMessage(err error, message string) error //只附加調用堆棧信息 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ù)生成錯誤,自帶調用堆棧信息。
// 例子 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,我們需要對他進行再次包裝處理,這時候有三個函數(shù)可以選擇。
//只附加新的信息 func WithMessage(err error, message string) error //只附加調用堆棧信息 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
這里只是簡單介紹相關函數(shù)的使用,我們可以自己對這些函數(shù)進行封裝,然后在相應的地方進行調用。
3、總結
通過使用這個 github.com/pkg/errors 錯誤庫,我們可以收集更多的信息,可以讓我們更容易的定位問題。
我們收集的這些信息不止可以輸出到控制臺,也可以當做日志,使用輸出到相應的 Log 日志里,便于分析問題。
以上就是Go語言中實現(xiàn)打印堆棧的errors包的用法詳解的詳細內容,更多關于Go語言打印堆棧errors包的資料請關注腳本之家其它相關文章!
相關文章
Golang使用Channel組建高并發(fā)HTTP服務器
Golang 作為一門高效的語言,在網(wǎng)絡編程方面表現(xiàn)也非常出色,這篇文章主要介紹了如何使用 Golang 和 Channel 組建高并發(fā) HTTP 服務器,感興趣的可以了解一下2023-06-06Prometheus Go client library使用方式詳解
這篇文章主要為大家介紹了Prometheus Go client library使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11go程序測試CPU占用率統(tǒng)計ps?vs?top兩種不同方式對比
這篇文章主要為大家介紹了go程序測試CPU占用率統(tǒng)計ps?vs?top兩種不同方式對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05