golang: How to Add Better Context to Errors
There are at least three ways to add more context to errors
.
package main
import (
"errors"
"fmt"
werr "github.com/pkg/errors"
"go.uber.org/zap"
)
// 1. wraps with a message
func wrap(e error) error {
return fmt.Errorf("another layer - %w", e)
}
// 2. wraps with callstack and message
func betterWrap(e error) error {
return werr.Wrap(e, "a better layer")
}
// 3. wraps with the first callstack frame
func zapLogger(e error) {
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
// Structured context as strongly typed Field values.
zap.Error(e))
}
func main() {
e := errors.New("a test err")
fmt.Printf("err= %+v\n", wrap(e))
fmt.Printf("%+v\n", betterWrap(e))
zapLogger(e)
}
Execution
$ go run err_context.go
fmt.errorf
err= another layer - a test err
errors package
a test err
a better layer
main.betterWrap
/Users/xxx/go-code/blog/err/err_context.go:18
main.main
/Users/xxx/go-code/blog/err/err_context.go:35
runtime.main
/Users/xxx/.goenv/versions/1.14.0/src/runtime/proc.go:203
runtime.goexit
/Users/xxx/.goenv/versions/1.14.0/src/runtime/asm_amd64.s:1373
zap
{"level":"info","ts":1604374256.270431,"caller":"err/err_context.go:25",
"msg":"failed to fetch URL","error":"a test err"}
Conclusion
I like the errors package the most. It has a relevant context to troubleshoot a problem.