github.com/ShoshinNikita/go-errors
github.com/ShoshinNikita/go-errors
is like github.com/pkg/errors
but with some improvements:
- it prints only the deepest stack trace
- it filters
runtime
calls in stack traces - it wraps a special error (see
ErrNilWrap
) ifWrap
/Wrapf
is called withnil
error
Example
Consider the following code
package main
import (
"fmt"
"github.com/pkg/errors"
)
func main() {
fmt.Printf("%+v\n", foo())
}
func foo() error { return errors.Wrap(bar(), "foo") }
func bar() error { return errors.Wrap(errors.New("original err"), "bar") }
It prints 3 stack traces. And most of the stack frames are just repeated
original err
main.bar
./main.go:14
main.foo
./main.go:13
main.main
./main.go:10
runtime.main
runtime/proc.go:255
runtime.goexit
runtime/asm_amd64.s:1581
bar
main.bar
./main.go:14
main.foo
./main.go:13
main.main
./main.go:10
runtime.main
runtime/proc.go:255
runtime.goexit
runtime/asm_amd64.s:1581
foo
main.foo
./main.go:13
main.main
./main.go:10
runtime.main
runtime/proc.go:255
runtime.goexit
runtime/asm_amd64.s:1581
If we replace github.com/pkg/errors
with github.com/ShoshinNikita/go-errors
, we will get only the deepest stack trace. Additionally, all runtime
calls will be filtered
foo: bar: original err
main.bar
./main.go:14
main.foo
./main.go:13
main.main
./main.go:10
Benchmarks
You can use this command BENCH=. make bench
to run all benchmarks
name time/op
Wrap/go-errors/few (2) 4.92µs ± 7%
Wrap/go-errors/medium (5) 12.5µs ± 3%
Wrap/go-errors/many (10) 27.3µs ± 2%
Wrap/pkg_errors/few (2) 4.27µs ± 8%
Wrap/pkg_errors/medium (5) 11.5µs ± 8%
Wrap/pkg_errors/many (10) 25.6µs ± 2%
Wrap/fmt/few (2) 1.01µs ± 4%
Wrap/fmt/medium (5) 2.61µs ± 2%
Wrap/fmt/many (10) 5.43µs ± 9%
Format/go-errors 18.3µs ± 5%
Format/pkg_errors 108µs ± 2%
Format/fmt 208ns ± 2%
name alloc/op
Wrap/go-errors/few (2) 720B ± 0%
Wrap/go-errors/medium (5) 1.66kB ± 0%
Wrap/go-errors/many (10) 3.28kB ± 0%
Wrap/pkg_errors/few (2) 672B ± 0%
Wrap/pkg_errors/medium (5) 1.68kB ± 0%
Wrap/pkg_errors/many (10) 3.36kB ± 0%
Wrap/fmt/few (2) 128B ± 0%
Wrap/fmt/medium (5) 368B ± 0%
Wrap/fmt/many (10) 816B ± 0%
Format/go-errors 17.9kB ± 0%
Format/pkg_errors 1.42kB ± 0%
Format/fmt 0.00B
name allocs/op
Wrap/go-errors/few (2) 9.00 ± 0%
Wrap/go-errors/medium (5) 16.0 ± 0%
Wrap/go-errors/many (10) 27.0 ± 0%
Wrap/pkg_errors/few (2) 8.00 ± 0%
Wrap/pkg_errors/medium (5) 20.0 ± 0%
Wrap/pkg_errors/many (10) 40.0 ± 0%
Wrap/fmt/few (2) 4.00 ± 0%
Wrap/fmt/medium (5) 10.0 ± 0%
Wrap/fmt/many (10) 20.0 ± 0%
Format/go-errors 53.0 ± 0%
Format/pkg_errors 155 ± 0%
Format/fmt 0.00