golang pkg/errors如何打印自定义的包装错误?

huangapple go评论82阅读模式
英文:

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()
	// 可以打印错误堆栈
	exitf("Error1: %+v", err)

	fmt.Println()
	fmt.Println()
	// 无法打印错误堆栈
	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)获取原始错误,然后打印它,但这意味着我需要在每次打印之前都这样做,这不是很优雅的代码,我真的不想这样做...

这是一个示例项目:https://github.com/lianxmfor/play_error

英文:

My project wraps a custom error type errNotFound, which has an error embedded in it.
Now I have a pkg/errors package that generates an error that prints the call stack. But when I inline this error into errNotFound, the call stack is not printed. Here is a sample, how can I change it?

simple:

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{})
}

output:

$ 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

I know I can get the original error by err = errors.Unwrap(err) and then print it, but this means that I need to do this every time before printing, which is not very elegant code, and I don't really want to do that...

here is an example project: https://github.com/lianxmfor/play_error

答案1

得分: 1

如果你已经有了堆栈,是否有必要在另一个if语句中放置一个错误?

如果是的话...你可以为errNotFound定义一个方法,如下所示:

func (e errNotFound) Error() string {
    return fmt.Printf("NotFound: %+v", e.err)
}
英文:

Is this necessary to put an error inside another if you already have your stack?

If yes... You can define a Method for errNotFound like:

func (e errNotFound) Error() string {
    return fmt.Printf("NotFound: %+v", e.err)
}

答案2

得分: 0

你需要使用堆栈注释错误:

func ErrNotFound(err error) error {
        if err == nil || IsErrNotFound(err) {
                return err
        }

        return errors.WithStack(errNotFound{err})
}
英文:

you need to annotate the error with stack:

func ErrNotFound(err error) error {
        if err == nil || IsErrNotFound(err) {
                return err
        }

        return errors.WithStack(errNotFound{err})
}

答案3

得分: 0

在调用exitf时,你可以使用errors.WithStack来打印堆栈跟踪。

英文:

while calling exitf you can use errors.WithStack to print stack trace.

huangapple
  • 本文由 发表于 2022年1月25日 23:34:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/70851429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定