Go package for errors with chained stack traces

errstack: Go errors with chained stack traces

errstack is a Go package for creating errors with stack traces. It is heavily inspired by github.com/pkg/errors, as well as chained exceptions as seen in Java and Python 3.

There are two basic operations with errstack: creating a new error, and wrapping an existing one to add a stack trace.

Creating a new error

To create a new error, simply use the New() constructor:

import "github.com/gward/errstack"

err := errstack.New("something is broken")

This error object behaves very similarly to an error from the standard errors package, but it remembers the call stack from where it was created. This allows it to generate a stack trace on demand.

errstack also provides an Errorf() function, very similar to fmt.Errorf() from the standard library:

err := errstack.Errorf("%s is broken", "something")

Both of these constructors return an instance of ErrorStack.

Wrapping an existing error

If you are dealing with a library whose errors do not include stack traces, you may want to add a stack trace to those errors. Use the Wrap() function for this:

result, err := otherlib.DoSomething(...)
if err != nil {
	err := errstack.Wrap(err, "failed to do something")
	return err
}

Like the constructors, Wrap() returns an ErrorStack object.

By default, repeated application of Wrap() results in a chain of stack traces:

outermost error:
testapp.layer1()
	testapp/main.go:23
testapp.main()
	testapp/main.go:11
runtime.main()
	/usr/lib/go-1.17/src/runtime/proc.go:255

middle error:
testapp.layer3()
	testapp/main.go:47
testapp.layer2()
	testapp/main.go:43
testapp.layer1()
	testapp/main.go:21

innermost error:
testapp.layer4()
	testapp/main.go:53
testapp.layer3()
	testapp/main.go:45

This tells you that the error originated in layer4(), at line 53 (or line 53 received an error without a stack trace, and wrapped it). That error was passed up from layer4() to layer3(), which wrapped it at line 47. Then it propagated up the stack to layer1(), which wrapped it again at line 23.

(You may be familiar with chained stack traces from exceptions in Java or Python 3.)

Accessing a stack trace

There are several ways to extract the stack trace from an ErrorStack. You can format it with %+v:

if err != nil {
	fmt.Printf(os.Stderr, "got an error: %+v\n", err)
}

(The formatted string is a multiline string with no trailing newline.)

This is handy because it works with any error object -- there is no need for a type assertion or type switch.

If you already know the error object is an ErrorStack, you can use WriteStack() or FormatStack():

// In real life, you would do this in a less panic-prone way.
esErr := err.(errstack.ErrorStack)

// Write a stack trace to a Writer (with trailing newline).
esErr.WriteStack(os.Stderr)

// Get a slice of lines that can be written.
lines := esErr.FormatStack()
for _, line := range lines {
	fmt.Fprintln(os.Stderr, line)
}

Finally, you can use either StackTrace() or StackChain() to get an object representing a single stack trace or a chain of stack traces.

StackTrace() returns a StackTrace object, which represents a single stack trace. For a multiply wrapped error that chains several stack traces, this will be the outermost stack trace, which is usually not what you want. Use StackChain() to get the full chain of stack traces as a StackChain object.

See the API reference for more details on working with StackTrace and StackChain objects.

Similar Resources

This structured Error package wraps errors with context and other info

RErr package This structured Error package wraps errors with context and other info. It can be used to enrich logging, for example with a structured l

Jan 21, 2022

The Emperor takes care of all errors personally

The Emperor takes care of all errors personally

The Emperor takes care of all errors personally. Go's philosophy encourages to gracefully handle errors whenever possible, but some times recovering f

Jan 9, 2023

eris provides a better way to handle, trace, and log errors in Go 🎆

eris Package eris provides a better way to handle, trace, and log errors in Go. go get github.com/rotisserie/eris Why you'll want to switch to eris Us

Dec 29, 2022

A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.

A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.

Errors Errors package is a drop-in replacement of the built-in Go errors package with no external dependencies. It lets you create errors of 11 differ

Dec 6, 2022

Hierarchical errors reporting done right in Golang

Hierarchical errors made right Hate seeing error: exit status 128 in the output of programs without actual explanation what is going wrong? Or, maybe,

Nov 9, 2021

Go tool to wrap and fix errors with the new %w verb directive

Go tool to wrap and fix errors with the new %w verb directive

errwrap Wrap and fix Go errors with the new %w verb directive. This tool analyzes fmt.Errorf() calls and reports calls that contain a verb directive t

Nov 10, 2022

Golang errors with stacktrace and context

merry Add context to errors, including automatic stack capture, cause chains, HTTP status code, user messages, and arbitrary values. The package is la

Nov 19, 2022

harvest Go errors with ease

Pears Harvest Go Errors with Ease Introduction Pears helps reduce the boilerplate and ensure correctness for common error-handling scenarios: Panic re

Apr 25, 2021

SupErr -- Go stdlib errors with super powers

superr SupErr -- Go stdlib errors with super powers. Pronounced super with a French accent :D Build a stack of errors compatible with Go stdlib and er

Nov 15, 2022
An errors package optimized for the pkg/errors package
An errors package optimized for the pkg/errors package

errors An errors package optimized for the pkg/errors package Use Download and install go get github.com/dobyte/errors API // New Wrapping for errors.

Mar 2, 2022
Drop-in replacement for the standard library errors package and github.com/pkg/errors

Emperror: Errors Drop-in replacement for the standard library errors package and github.com/pkg/errors. This is a single, lightweight library merging

Dec 20, 2022
A Go package providing errors with a stack trace Read-only

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

Sep 23, 2022
Common juju errors and functions to annotate errors. Based on juju/errgo

errors import "github.com/juju/errors" The juju/errors provides an easy way to annotate errors without losing the original error context. The exporte

Dec 30, 2022
Linter for errors.Is and errors.As

erris erris is a program for checking that errors are compared or type asserted using go1.13 errors.Is and errors.As functions. Install go get -u gith

Nov 27, 2022
Golang errors with stack trace and source fragments.
Golang errors with stack trace and source fragments.

Golang Errors with Stack Trace and Source Fragments Tired of uninformative error output? Probably this will be more convenient: Example package main

Dec 17, 2022
A simple errors package that dynamically prepends the package name.

errors ?? Buy me a cookie What is this? A simple errors package that dynamically prepends the package name. How to install Open a terminal and run the

Jan 16, 2022
A Go (golang) package for representing a list of errors as a single error.

go-multierror go-multierror is a package for Go that provides a mechanism for representing a list of error values as a single error. This allows a fun

Jan 1, 2023
Package semerr helps to work with errors in Golang.
Package semerr helps to work with errors in Golang.

semerr Package semerr helps to work with errors in Golang. Const error An error that can be defined as const. var errMutable error = errors.New("mutab

Oct 30, 2022
A Nostress Errors Package For Golang

A Nostress Errors Package For Golang

Nov 2, 2021