Errors with a stack trace
A Go package providing errors with a stack trace.
Features:
- Based of
github.com/pkg/errors
with similar API, addressing many its open issues. In many cases it can be used as a drop-in replacement. At the same time compatible withgithub.com/pkg/errors
errors. - Uses standard error wrapping (available since Go 1.13).
- Provides
errors.Errorf
which supports%w
format verb to both wrap and record a stack trace at the same time (if not already recorded). - Provides
errors.E
type to be used instead of standarderror
to annotate which functions return errors with a stack trace. - Clearly defines what are differences and expected use cases for:
errors.Errorf
: creating a new error and recording a stack trace, optionally wrapping an existing errorerrors.WithStack
: adding a stack trace to an error without oneerrors.WithMessage
: adding a prefix to the error messageerrors.Wrap
: creating a new error but recording its cause
- Provides
errors.Base
function to create errors without a stack trace to be used as base errors forerrors.Is
anderrors.As
. - Differentiates between wrapping and recording a cause: only
errors.Wrap
records a cause, while other functions are error transformers, wrapping the original. - Novice friendly formatting of a stack trace when error is formatted using
%+v
: tells what is the order of the stack trace and what is the relation between wrapped errors. - Makes sure a stack trace is not recorded multiple times unnecessarily.
- Errors implement
MarshalJSON
and can be marshaled into JSON.
Installation
This is a Go package. You can add it to your project using go get
:
go get gitlab.com/tozd/go/errors
Usage
See full package documentation with examples on pkg.go.dev.
Why a new Go errors package?
I find github.com/pkg/errors
package amazing. But the project is archived and not developed anymore, with many issues not addressed (primarily because many require some backward incompatible change). At the same time it has been made before Go 1.13 added official support for wrapping errors and it does not (and cannot, in backwards compatible way) fully embrace it. This package takes what is best from github.com/pkg/errors
, but breaks things a bit to address many of the open issues community has identified since then and to modernize it to today's Go.
github.com/pkg/errors
?
What are main differences from - The
stackTracer
interface'sStackTrace()
method returns[]uintptr
and not custom typeStackTrace
. - All error-wrapping functions return errors which implement the standard
unwrapper
interface, but onlyerrors.Wrap
records a cause error and returns an error which implements thecauser
interface. - All error-wrapping functions wrap the error into only one new error.
Errorf
supports%w
.- Errors formatted using
%+v
include linesStack trace (most recent call first):
andThe above error was caused by the following error:
to make it clearer how is the stack trace formatted and how are multiple errors related to each other. - Only
errors.Wrap
always records the stack trace while other functions do not record if it is already present. errors.Cause
repeatedly unwraps the error until it finds one which implements thecauser
interface, and then return its cause.