This repository was archived by the owner on Dec 1, 2021. It is now read-only.
This repository was archived by the owner on Dec 1, 2021. It is now read-only.
WriteStack() duplicates call stack if err is already a causer #158
Open
Description
package main
import (
"fmt"
"github.com/pkg/errors"
)
func GiveError() error {
return errors.New("this is an error")
}
func Outer() error {
err := GiveError()
return errors.WithStack(err)
}
func main() {
err := Outer()
fmt.Printf("%+v\n", err)
}
Output:
this is an error
main.GiveError
/Users/brianwong/go/src/github.com/brianbwong/test.go:9
main.Outer
/Users/brianwong/go/src/github.com/brianbwong/test.go:13
main.main
/Users/brianwong/go/src/github.com/brianbwong/test.go:18
runtime.main
/usr/local/opt/go/libexec/src/runtime/proc.go:198
runtime.goexit
/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:2361
main.Outer
/Users/brianwong/go/src/github.com/brianbwong/test.go:14
main.main
/Users/brianwong/go/src/github.com/brianbwong/test.go:18
runtime.main
/usr/local/opt/go/libexec/src/runtime/proc.go:198
runtime.goexit
/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:2361
In this toy example, it's obvious that the output of GiveError() already contains a stack trace, so there's no point in Wrapping it. However, if GiveError() is a function in an external package, it won't be clear whether its output contains a stack trace or not (and hence whether it needs wrapping).
If this isn't intended, here's a rough proposal for a fix:
// WithStack annotates err with a stack trace at the point WithStack was called.
// If err is nil, WithStack returns nil.
func WithStack(err error) error {
if err == nil {
return nil
}
_, ok := err.(causer)
if ok {
return err
}
return &withStack{
err,
callers(),
}
}
Though currently it looks like the type fundamental
isn't actually a causer
.
Happy to submit a PR if desired!
Metadata
Metadata
Assignees
Labels
No labels