golang pkg/errors 如何打印自定义包装错误?
golang pkg/errors How to print custom wrapped errors?
我的项目包装了一个自定义错误类型 errNotFound
,其中嵌入了一个错误。
现在我有一个 pkg/errors 包,它会生成打印调用堆栈的错误。但是,当我将此错误内联到 errNotFound 时,不会打印调用堆栈。这是一个示例,我该如何更改它?
简单:
package main
import (
"fmt"
stderrors "errors"
"github.com/pkg/errors"
)
func findSomething() error {
return errors.Errorf("something not found")
}
func main() {
err := findSomething()
// can print error stack
exitf("Error1: %+v", err)
fmt.Println()
fmt.Println()
// cannot print error stack
err = ErrNotFound(err)
exitf("Error2: %+v", err)
}
func exitf(format string, args ...interface{}) {
fmt.Printf(format, args...)
//os.Exit(1)
}
type errNotFound struct{ error }
func ErrNotFound(err error) error {
if err == nil || IsErrNotFound(err) {
return err
}
return errNotFound{err}
}
func IsErrNotFound(err error) bool {
return stderrors.As(err, &errNotFound{})
}
输出:
$ go run main
Error1: something not found
main.findSomething
/home/lianxm/github.com/play_error/main.go:11
main.main
/home/lianxm/github.com/play_error/main.go:15
runtime.main
/usr/local/go/src/runtime/proc.go:255
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1581
Error2: something not found
我知道我可以通过err = errors.Unwrap(err)
得到原始错误然后打印出来,但是这意味着我每次打印前都需要这样做,这不是很优雅的代码,我不会真的很想那样做...
如果您已经有了堆栈,是否有必要将错误放入另一个堆栈中?
如果是...您可以为 errNotFound 定义一个方法,例如:
func (e errNotFound) Error() string {
return fmt.Printf("NotFound: %+v", e.err)
}
你需要用堆栈注释错误:
func ErrNotFound(err error) error {
if err == nil || IsErrNotFound(err) {
return err
}
return errors.WithStack(errNotFound{err})
}
在调用 exitf
时,您可以使用 errors.WithStack 打印堆栈跟踪。
我的项目包装了一个自定义错误类型 errNotFound
,其中嵌入了一个错误。
现在我有一个 pkg/errors 包,它会生成打印调用堆栈的错误。但是,当我将此错误内联到 errNotFound 时,不会打印调用堆栈。这是一个示例,我该如何更改它?
简单:
package main
import (
"fmt"
stderrors "errors"
"github.com/pkg/errors"
)
func findSomething() error {
return errors.Errorf("something not found")
}
func main() {
err := findSomething()
// can print error stack
exitf("Error1: %+v", err)
fmt.Println()
fmt.Println()
// cannot print error stack
err = ErrNotFound(err)
exitf("Error2: %+v", err)
}
func exitf(format string, args ...interface{}) {
fmt.Printf(format, args...)
//os.Exit(1)
}
type errNotFound struct{ error }
func ErrNotFound(err error) error {
if err == nil || IsErrNotFound(err) {
return err
}
return errNotFound{err}
}
func IsErrNotFound(err error) bool {
return stderrors.As(err, &errNotFound{})
}
输出:
$ go run main
Error1: something not found
main.findSomething
/home/lianxm/github.com/play_error/main.go:11
main.main
/home/lianxm/github.com/play_error/main.go:15
runtime.main
/usr/local/go/src/runtime/proc.go:255
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1581
Error2: something not found
我知道我可以通过err = errors.Unwrap(err)
得到原始错误然后打印出来,但是这意味着我每次打印前都需要这样做,这不是很优雅的代码,我不会真的很想那样做...
如果您已经有了堆栈,是否有必要将错误放入另一个堆栈中?
如果是...您可以为 errNotFound 定义一个方法,例如:
func (e errNotFound) Error() string {
return fmt.Printf("NotFound: %+v", e.err)
}
你需要用堆栈注释错误:
func ErrNotFound(err error) error {
if err == nil || IsErrNotFound(err) {
return err
}
return errors.WithStack(errNotFound{err})
}
在调用 exitf
时,您可以使用 errors.WithStack 打印堆栈跟踪。