What's the difference between these three functions from Go's standard packages:
errors.Wrapf()
Wrapf returns an error annotating err with a stack trace at the point Wrapf is called, and the format specifier. If err is nil, Wrapf returns nil.
errors.Errorf()
, provided an error via %w
format variableErrorf formats according to a format specifier and returns the string as a value that satisfies error. Errorf also records the stack trace at the point it was called.
fmt.Errorf()
, provided an error via %w
format variableErrorf formats according to a format specifier and returns the string as a value that satisfies error.
If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand. It is invalid to include more than one %w verb or to supply it with an operand that does not implement the error interface. The %w verb is otherwise a synonym for %v.
When one should be used instead of others?
First, a correction:
github.com/pkg/errors
is not part of the standard library! The standard errors
package has a much smaller API.
That said, github.com/pkg/errors
is very popular, and is maintained by some prominent Gophers. It is, however, largely (though not completely*) obsoleted by Go 1.13's extended error support.
Understanding the difference between those three functions requires a bit of a history lesson.
Prior to Go 1.13, there was no officially-recognized way to "wrap" errors. github.com/pkg/errors
filled this gap with the Wrap
and Wrapf
methods. This allowed wrapping an error with additional context (including a stack trace), while retaining the original error in pristine form.
When Go 1.13 was in development, github.com/pkg/errors
was used to influence the new API, but the final version differed slightly. Rather than Wrap
and Wrapf
methods, they decided to extend the fmt.Errorf
method with a new %w
verb, which would perform error wrapping for you.
This means that the following bits of code are roughly* equivalent:
import "github.com/pkg/errors"
/* snip */
return errors.Wrapf(err, "bad things")
// +build go1.13
import "fmt"
/* snip */
return fmt.Errorf("bad things: %w", err)
When Go 1.13 came out, and the %w
verb was added to fmt.Errorf
, github.com/pkg/errors
followed suit and added the same support, so now Wrapf
is effectively obsolete.
So this brings us to the present day recommendations:
github.com/pkg/errors.Errorf
to wrap errors.fmt.Errorf
from the standard library.errors.Wrapf
any more. It's for backward compatibility.*The standard library's error
package still does not include stack traces, so github.com/pkg/errors
is still popular for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With