Why go does not have nice backtraces
Collecting stacktraces is expensive, so the core language will never implement them for everything.
If you need your code to be highly performant then consider making a error wrapper that can be turned on/off based on a environment variable.
Simple fix
- import
github.com/pkg/errors
and use it instead oferrors
package (it is deprecated but works fine) - always
errors.Wrap
,errrors.New
, orerrors.Errorf
from “github.com/pkg/errors” when passing from outside your code or creating errors - when subsequently passing errors along, a
return err
and DO NOTreturn fmt.Errorf("building foo: %w", err)
(multiple wraps create multiple backtraces which is noisy but not a big problem, but using fmt.Errorf discards the backtrace) - in your main.go add this:
// go playground https://go.dev/play/p/n1gcwD-cv4K
import (
"fmt"
"github.com/pkg/errors"
)
type withStackTrace interface {
StackTrace() errors.StackTrace
}
func main() {
err := errors.New("example")
err = errors.Wrap(err, "more context")
if errWithStack, ok := err.(withStackTrace); ok {
fmt.Fprintf(os.Stderr, "%+v\n", errWithStack)
} else {
fmt.Fprintln(os.Stderr, "Warning: unable to print stacktrace: use `errors.Wrap`")
}
}
Nicer fix
Use a more complete solution like eris.