Documentation
¶
Overview ¶
Package errors provides simple error handling primitives and behavioral errors.
Hello there! Read the presentation http://dave.cheney.net/paste/gocon-spring-2016.pdf to see what the big deal is.
http://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully
Read this for asserting errors for their behaviour http://dave.cheney.net/2014/12/24/inspecting-errors
The traditional error handling idiom in Go is roughly akin to
if err != nil {
return err
}
which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
Adding context to an error ¶
The errors.Wrap function returns a new error that adds context to the original error by recording a stack trace at the point Wrap is called, and the supplied message. For example
_, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "read failed")
}
If additional control is required the errors.WithStack and errors.WithMessage functions destructure errors.Wrap into its component operations of annotating an error with a stack trace and an a message, respectively.
Retrieving the cause of an error ¶
Using errors.Wrap constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface
type causer interface {
Cause() error
}
can be inspected by errors.Cause. errors.Cause will recursively retrieve the topmost error which does not implement causer, which is assumed to be the original cause. For example:
switch err := errors.Cause(err).(type) {
case *MyError:
// handle specifically
default:
// unknown error
}
causer interface is not exported by this package, but is considered a part of stable public API.
Formatted printing of errors ¶
All error values returned from this package implement fmt.Formatter and can be formatted by the fmt package. The following verbs are supported
%s print the error. If the error has a Cause it will be
printed recursively
%v see %s
%+v extended format. Each Frame of the error's StackTrace will
be printed in detail.
Retrieving the stack trace of an error or wrapper ¶
New, Errorf, Wrap, and Wrapf record a stack trace at the point they are invoked. This information can be retrieved with the following interface.
type stackTracer interface {
StackTrace() errors.StackTrace
}
Where errors.StackTrace is defined as
type StackTrace []Frame
The Frame type represents a call site in the stack trace. Frame supports the fmt.Formatter interface that can be used for printing information about the stack trace of this error. For example:
if err, ok := err.(stackTracer); ok {
for _, f := range err.StackTrace() {
fmt.Printf("%+s:%d", f)
}
}
stackTracer interface is not exported by this package, but is considered a part of stable public API.
See the documentation for Frame.Format for more details.
Example (StackTrace) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func fn() error {
e1 := errors.New("error")
e2 := errors.Wrap(e1, "inner")
e3 := errors.Wrap(e2, "middle")
return errors.Wrap(e3, "outer")
}
func main() {
type stackTracer interface {
StackTrace() errors.StackTrace
}
err, ok := errors.Cause(fn()).(stackTracer)
if !ok {
panic("oops, err does not implement stackTracer")
}
st := err.StackTrace()
fmt.Printf("%+v", st[0:2]) // top two frames
// Example output:
// github.com/pkg/errors_test.fn
// /home/dfc/src/github.com/pkg/errors/example_test.go:47
// github.com/pkg/errors_test.Example_stackTrace
// /home/dfc/src/github.com/pkg/errors/example_test.go:127
}
Index ¶
- func Attach(err error, k Kind) error
- func Cause(err error) error
- func CausedBehaviour(err error, k Kind) bool
- func Detach(err error, k Kind) error
- func Errorf(format string, args ...interface{}) error
- func FormatLineFunc(errs []error) string
- func Is(err error, k Kind) bool
- func MarshalAppend(err error, b []byte) []byte
- func MatchAll(err error, k ...Kind) bool
- func MatchAny(err error, k ...Kind) bool
- func MultiErrMatchAll(err error, ks ...Kind) bool
- func MultiErrMatchAny(err error, ks ...Kind) bool
- func New(message string) error
- func Unmarshal(b []byte) error
- func UnwrapStack(err error) []byte
- func WithMessage(err error, message string) error
- func WithStack(err error) error
- func Wrap(err error, message string) error
- func Wrapf(err error, format string, args ...interface{}) error
- type ErrorFormatFunc
- type Frame
- type Kind
- type Kinder
- type Kinds
- type MultiErr
- type StackTrace
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Attach ¶
Attach adds Kind `k` to an error but only if the error has been created with this package. For example you can create a Restricted error and then attach a Temporary kind. Now the error has two kinds. If the error hasn't been created by this package, then nothing happens.
func Cause ¶
Cause returns the underlying cause of the error, if possible. An error value has a cause if it implements the following interface:
type causer interface {
Cause() error
}
If the error does not implement Cause, the original error will be returned. If the error is nil, nil will be returned without further investigation.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func fn() error {
e1 := errors.New("error")
e2 := errors.Wrap(e1, "inner")
e3 := errors.Wrap(e2, "middle")
return errors.Wrap(e3, "outer")
}
func main() {
err := fn()
fmt.Println(err)
fmt.Println(errors.Cause(err))
}
Output: outer: middle: inner: error error
Example (Printf) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
err := errors.Wrap(func() error {
return func() error {
return errors.Errorf("hello %s", fmt.Sprintf("world"))
}()
}(), "failed")
fmt.Printf("%v", err)
}
Output: failed: hello world
func CausedBehaviour ¶
CausedBehaviour returns the first underlying caused kind/behaviour of the error, if possible. An error value has a cause if it implements the following interface:
type Causer interface {
Cause() error
}
If the error does not implement Cause or is nil, false will be returned. The variable `k` gets called on each unwrapped "cause" error.
func Errorf ¶
Errorf 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.
Example (Extended) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
err := errors.Errorf("whoops: %s", "foo")
fmt.Printf("%+v", err)
// Example output:
// whoops: foo
// github.com/pkg/errors_test.ExampleErrorf
// /home/dfc/src/github.com/pkg/errors/example_test.go:101
// testing.runExample
// /home/dfc/go/src/testing/example.go:114
// testing.RunExamples
// /home/dfc/go/src/testing/example.go:38
// testing.(*M).Run
// /home/dfc/go/src/testing/testing.go:744
// main.main
// /github.com/pkg/errors/_test/_testmain.go:102
// runtime.main
// /home/dfc/go/src/runtime/proc.go:183
// runtime.goexit
// /home/dfc/go/src/runtime/asm_amd64.s:2059
}
func FormatLineFunc ¶
FormatLineFunc is a basic formatter that outputs the errors that occurred along with the filename and the line number of the errors. Only if the error has a Location() function.
func Is ¶
Is returns true if `err` is of Kind `k`. It unwraps all underlying errors which implement the Causer interface.
func MarshalAppend ¶
MarshalAppend marshals an arbitrary error into a byte slice. The result is appended to b, which may be nil. It returns the argument slice unchanged if the error is nil. If the error is not an *Error, it just records the result of err.Error(). Otherwise it encodes the full Error struct.
func MatchAll ¶
MatchAll checks if all Kinds are included in `err`. It does not unwrap `err` by its `Causer` interface.
func MatchAny ¶
MatchAny checks if at least one Kind is included in `err`. It does not unwrap `err` by its `Causer` interface.
func MultiErrMatchAll ¶
MultiErrMatchAll checks if err contains a behavioral error. 1st argument err must be of type (*MultiErr) and validate function vf at least one of the many Is*() e.g. IsNotValid(), see type BehaviourFunc. All validate functions must return true. If there are multiple behavioral errors and one BehaviourFunc it will stop after all errors matches the BehaviourFunc, not at the first match.
func MultiErrMatchAny ¶
MultiErrMatchAny checks if err contains at least one behavioral error. 1st argument err must be of type (*MultiErr) and validate function vf at least one of the many Is*() e.g. IsNotValid(), see type BehaviourFunc.
func New ¶
New returns an error with the supplied message. New also records the stack trace at the point it was called.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
err := errors.New("whoops")
fmt.Println(err)
}
Output: whoops
Example (Printf) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
err := errors.New("whoops")
fmt.Printf("%+v", err)
// Example output:
// whoops
// github.com/pkg/errors_test.ExampleNew_printf
// /home/dfc/src/github.com/pkg/errors/example_test.go:17
// testing.runExample
// /home/dfc/go/src/testing/example.go:114
// testing.RunExamples
// /home/dfc/go/src/testing/example.go:38
// testing.(*M).Run
// /home/dfc/go/src/testing/testing.go:744
// main.main
// /github.com/pkg/errors/_test/_testmain.go:106
// runtime.main
// /home/dfc/go/src/runtime/proc.go:183
// runtime.goexit
// /home/dfc/go/src/runtime/asm_amd64.s:2059
}
func Unmarshal ¶
Unmarshal unmarshals the byte slice into an error value. If the slice is nil or empty, it returns nil. Otherwise the byte slice must have been created by `Marshal` or `MarshalAppend`. If the encoded error was of type `errors` within this package, the returned error value will have that underlying type. Otherwise it will be just a simple value that implements the error interface.
func UnwrapStack ¶
UnwrapStack tries to extract the previous stack trace after unmarshalling a byte slice into an error. It can return nil.
func WithMessage ¶
WithMessage annotates err with a new message. If err is nil, WithMessage returns nil.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
cause := errors.New("whoops")
err := errors.WithMessage(cause, "oh noes")
fmt.Println(err)
}
Output: oh noes: whoops
func WithStack ¶
WithStack annotates err with a stack trace at the point WithStack was called. If err is nil, WithStack returns nil.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
cause := errors.New("whoops")
err := errors.WithStack(cause)
fmt.Println(err)
}
Output: whoops
Example (Printf) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
cause := errors.New("whoops")
err := errors.WithStack(cause)
fmt.Printf("%+v", err)
// Example Output:
// whoops
// github.com/pkg/errors_test.ExampleWithStack_printf
// /home/fabstu/go/src/github.com/pkg/errors/example_test.go:55
// testing.runExample
// /usr/lib/go/src/testing/example.go:114
// testing.RunExamples
// /usr/lib/go/src/testing/example.go:38
// testing.(*M).Run
// /usr/lib/go/src/testing/testing.go:744
// main.main
// github.com/pkg/errors/_test/_testmain.go:106
// runtime.main
// /usr/lib/go/src/runtime/proc.go:183
// runtime.goexit
// /usr/lib/go/src/runtime/asm_amd64.s:2086
// github.com/pkg/errors_test.ExampleWithStack_printf
// /home/fabstu/go/src/github.com/pkg/errors/example_test.go:56
// testing.runExample
// /usr/lib/go/src/testing/example.go:114
// testing.RunExamples
// /usr/lib/go/src/testing/example.go:38
// testing.(*M).Run
// /usr/lib/go/src/testing/testing.go:744
// main.main
// github.com/pkg/errors/_test/_testmain.go:106
// runtime.main
// /usr/lib/go/src/runtime/proc.go:183
// runtime.goexit
// /usr/lib/go/src/runtime/asm_amd64.s:2086
}
func Wrap ¶
Wrap returns an error annotating err with a stack trace at the point Wrap is called, and the supplied message. If err is nil, Wrap returns nil.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
cause := errors.New("whoops")
err := errors.Wrap(cause, "oh noes")
fmt.Println(err)
}
Output: oh noes: whoops
Example (Extended) ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func fn() error {
e1 := errors.New("error")
e2 := errors.Wrap(e1, "inner")
e3 := errors.Wrap(e2, "middle")
return errors.Wrap(e3, "outer")
}
func main() {
err := fn()
fmt.Printf("%+v\n", err)
// Example output:
// error
// github.com/pkg/errors_test.fn
// /home/dfc/src/github.com/pkg/errors/example_test.go:47
// github.com/pkg/errors_test.ExampleCause_printf
// /home/dfc/src/github.com/pkg/errors/example_test.go:63
// testing.runExample
// /home/dfc/go/src/testing/example.go:114
// testing.RunExamples
// /home/dfc/go/src/testing/example.go:38
// testing.(*M).Run
// /home/dfc/go/src/testing/testing.go:744
// main.main
// /github.com/pkg/errors/_test/_testmain.go:104
// runtime.main
// /home/dfc/go/src/runtime/proc.go:183
// runtime.goexit
// /home/dfc/go/src/runtime/asm_amd64.s:2059
// github.com/pkg/errors_test.fn
// /home/dfc/src/github.com/pkg/errors/example_test.go:48: inner
// github.com/pkg/errors_test.fn
// /home/dfc/src/github.com/pkg/errors/example_test.go:49: middle
// github.com/pkg/errors_test.fn
// /home/dfc/src/github.com/pkg/errors/example_test.go:50: outer
}
func Wrapf ¶
Wrapf returns an error annotating err with a stack trace at the point Wrapf is call, and the format specifier. If err is nil, Wrapf returns nil.
Example ¶
package main
import (
"fmt"
"github.com/corestoreio/errors"
)
func main() {
cause := errors.New("whoops")
err := errors.Wrapf(cause, "oh noes #%d", 2)
fmt.Println(err)
}
Output: oh noes #2: whoops
Types ¶
type ErrorFormatFunc ¶
ErrorFormatFunc is a function callback that is called by Error to turn the list of errors into a string.
type Frame ¶
type Frame uintptr
Frame represents a program counter inside a stack frame.
func (Frame) Format ¶
Format formats the frame according to the fmt.Formatter interface.
%s source file %d source line %n function name %v equivalent to %s:%d
Format accepts flags that alter the printing of some verbs, as follows:
%+s function name and path of source file relative to the compile time
GOPATH separated by \n\t (<funcname>\n\t<path>)
%+v equivalent to %+s:%d
type Kind ¶
type Kind uint64
Kind defines the kind or behaviour of an error. An error can have multiple Kinds wrapped into each other via bit operations. A zero Kind represents an empty Kind. The underlying type uint might change, so please use the functions provided in this package to manipulate the Kind. 63 different constants are currently supported.
const ( Aborted Kind = 1 << iota AlreadyCaptured AlreadyClosed AlreadyExists AlreadyInUse AlreadyRefunded Blocked ReadFailed WriteFailed VerificationFailed DecryptionFailed EncryptionFailed ConnectionFailed BadEncoding ConnectionLost Declined Denied Duplicated NotEmpty Empty Exceeded Exists NotExists Expired Fatal InProgress Insufficient Interrupted IsDirectory IsFile NotDirectory NotFile Locked Mismatch NotAcceptable NotAllowed NotFound NotImplemented NotRecoverable NotSupported NotValid Overflowed PermissionDenied UserNotFound QuotaExceeded Rejected Required Restricted Revoked Temporary Terminated Timeout TooLarge WrongVersion CorruptData OutofRange )
These constants define different behaviours. They are not sorted and new constants must be appended at the end. The zero kind defines empty.
const NoKind Kind = 0
NoKind defines an empty Kind with no behaviour. This constant must be placed outside the constant block to avoid a conflict with iota.
func UnwrapKind ¶
UnwrapKind extract the Kind of an error. If the error has not been created via this package or does not implement interface `Kinder`, this function will return zero.
func (Kind) New ¶
New wraps err with the specified Kind. Allows to write an additional message which gets formatted by fmt.Sprintf.
type Kinder ¶
type Kinder interface {
ErrorKind() Kind
}
Kinder may be implemented by any other custom error type to define desired kinds/behaviours. Multiple Kinds can be returned.
type Kinds ¶
type Kinds []Kind
Kinds a slice of Kind. Each Kind does not contain any other Kind.
func UnwrapKinds ¶
UnwrapKinds checks if error has a Kind/behaviour and returns a slice with all found Kinds. The returned slice is sorted numerical.
type MultiErr ¶
type MultiErr struct {
Errors []error
Formatter ErrorFormatFunc
}
MultiErr represents a container for collecting and printing multiple errors.
func NewMultiErr ¶
NewMultiErr creates a new multi error struct.
func (*MultiErr) AppendErrors ¶
AppendErrors adds multiple errors to the container. Does not add a location. If *MultiErr is nil it creates a new pointer and returns it.
type StackTrace ¶
type StackTrace []Frame
StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
func (StackTrace) Format ¶
func (st StackTrace) Format(s fmt.State, verb rune)
Format formats the stack of Frames according to the fmt.Formatter interface.
%s lists source files for each Frame in the stack %v lists the source file and line number for each Frame in the stack
Format accepts flags that alter the printing of some verbs, as follows:
%+v Prints filename, function, and line number for each Frame in the stack.