1

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
  • maybe errorNotFound implement fmt.Formatter can solve this, but i cannot how to implement the interface 😿 Commented Jan 25, 2022 at 15:42

3 Answers 3

1

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) } 
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, I need to put the error in errNotFound, which is very useful for me, see here: go.dev/play/p/VNJBWfbhhQZ
This method solves my problem, thank you!
0

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

1 Comment

Yes, I can do that, thank you! But that would print out multiple call stacks, which I don't really want to do.
0

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

1 Comment

This has the same effect as calling errors.Unwrap before each exitf call, which I don't really want to do, it's not very elegant

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.