Documentation
¶
Overview ¶
Package oops adds detailed stacktraces to your Go errors.
To use the oops package, calls oops.Errorf when creating a new error, and oops.Wrapf when returning nested errors. To access the original error, use oops.Cause. Each function in the callstack can add extra debugging information to help you track down errors.
An example error (from the program below) looks as follows:
20 is too large! main.Foo github.com/samsarahq/go/oops/example/main.go:12 main.Legacy github.com/samsarahq/go/oops/example/main.go:19 main.Bar: Legacy(20) didn't work github.com/samsarahq/go/oops/example/main.go:24 main.Go.func1 github.com/samsarahq/go/oops/example/main.go:35 main.Go: goroutine had a problem github.com/samsarahq/go/oops/example/main.go:38 main.main github.com/samsarahq/go/oops/example/main.go:42 runtime.main runtime/proc.go:185
The first time oops.Errorf or oops.Wrapf is called, it captures a stacktrace. To keep your stacktraces as detailed as possible, it is best to call oops.Wrapf every time you return an error. If you have no context to add, you can always pass an empty format string to oops.Wrapf.
When adding oops to an existing package or program, you might have intermediate functions that don't yet call oops.Wrapf when returning errors. That is no problem, as later calls to oops.Wrapf will attach their messages to right stackframe. However, you might as well add oops.Wrapf there as well!
Usage:
package main import ( "fmt" "github.com/samsarahq/go/oops" ) // Foo creates new errors using oops.Errorf. func Foo(i int) error { if i > 10 { return oops.Errorf("%d is too large!", i) } return nil } // Legacy is old code that does not use oops. func Legacy(i int) error { return Foo(i) } // Bar wraps errors using Wrapf. func Bar() error { if err := Legacy(20); err != nil { return oops.Wrapf(err, "Legacy(20) didn't work") } return nil } // Go wraps errors using Wrapf after receiving one from a channel! func Go() error { ch := make(chan error) go func() { ch <- Bar() }() return oops.Wrapf(<-ch, "goroutine had a problem") } func main() { if err := Go(); err != nil { fmt.Print(err) } }
Index ¶
- func As(err error, target interface{}) bool
- func Cause(err error) error
- func Errorf(format string, a ...interface{}) error
- func Frames(err error) [][]Frame
- func Is(err, target error) bool
- func MainStackToString(err error) string
- func Recover(p interface{}) error
- func SkipFrames(err error, numFrames int) error
- func Unwrap(err error) error
- func Wrapf(err error, format string, a ...interface{}) error
- type Frame
- type Wrapper
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func As ¶
As finds the first error in err's chain that matches the type to which target points, and if so, sets the target to its value and returns true. An error matches a type if it is assignable to the target type, or if it has a method As(interface{}) bool such that As(target) returns true. As will panic if target is not a non-nil pointer to a type which implements error or is of interface type.
The As method should set the target to its value and return true if err matches the type to which target points.
func Cause ¶
Cause extracts the cause error of an oops error. If err is not an oops error, err itself is returned.
You can use Cause to check if an error is an expected error. For example, if you know than EOF error is fine, you can handle it with Cause.
func Errorf ¶
Errorf creates a new error with a reason and a stacktrace.
Use Errorf in places where you would otherwise return an error using fmt.Errorf or errors.New.
Note that the result of Errorf includes a stacktrace. This means that Errorf is not suitable for storing in global variables. For such errors, keep using errors.New.
func Frames ¶
Frames extracts all frames from an oops error. If err is not an oops error, nil is returned.
func Is ¶
Is reports whether any error in err's chain matches target.
An error is considered to match a target if it is equal to that target or if it implements a method Is(error) bool such that Is(target) returns true.
func MainStackToString ¶
MainStackToString will write the frames of the main goroutine to a string. This will return an empty string if the error is not an oopsError.
func Recover ¶
func Recover(p interface{}) error
Recover recovers from a panic in a defer. If there is no panic, Recover() returns nil. To use, call oops.Recover(recover()) and compare the result to nil.
func SkipFrames ¶
SkipFrames skips numFrames from the stack trace and returns a new copy of the error. If numFrames is greater than the number of frames in err, SkipFrames will do nothing and return the original err.
func Unwrap ¶
Unwrap returns the result of calling the Unwrap method on err, if err implements Unwrap. Otherwise, Unwrap returns nil.
func Wrapf ¶
Wrapf annotates an error with a reason and a stacktrace. If err is nil, Wrapf returns nil.
Use Wrapf in places where you would otherwise return an error directly. If the error passed to Wrapf is nil, Wrapf will also return nil. This makes it safe to use in one-line return statements.
To check if a wrapped error is a specific error, such as io.EOF, you can extract the error passed in to Wrapf using Cause.