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 }
Output:
Index ¶
- Constants
- 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 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 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 Frame
- type Kind
- func (k Kind) Empty() bool
- func (k Kind) Error() string
- func (k Kind) Match(err error) bool
- func (k Kind) MatchInterface(err error) bool
- func (k Kind) New(err error, msg string, args ...interface{}) error
- func (k Kind) Newf(format string, args ...interface{}) error
- func (k Kind) String() string
- func (k Kind) Unwrap() Kinds
- type Kinder
- type Kinds
- type StackTrace
Examples ¶
Constants ¶
const KindSeparator = "|"
KindSeparator separates multiple Kinds packed into one Kind.
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 }
Output:
func Is ¶
Is returns true if `err` is of Kind `k`. It unwraps all underlying errors which implement the Causer interface. Does not supported implemented behaviour functions.
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. Does not supported implemented behaviour functions.
func MatchAny ¶
MatchAny checks if at least one Kind is included in `err`. It does not unwrap `err` by its `Causer` interface. Does not supported implemented behaviour functions.
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 }
Output:
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 }
Output:
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 }
Output:
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 Frame ¶
type Frame uintptr
Frame represents a program counter inside a stack frame. For historical reasons if Frame is interpreted as a uintptr its value represents the program counter + 1.
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
func (Frame) MarshalText ¶
MarshalText formats a stacktrace Frame as a text string. The output is the same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.
type Kind ¶
type Kind string
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 = "Aborted" AlreadyCaptured Kind = "AlreadyCaptured" AlreadyClosed Kind = "AlreadyClosed" AlreadyExists Kind = "AlreadyExists" AlreadyInUse Kind = "AlreadyInUse" AlreadyRefunded Kind = "AlreadyRefunded" BadEncoding Kind = "BadEncoding" Blocked Kind = "Blocked" ConnectionFailed Kind = "ConnectionFailed" ConnectionLost Kind = "ConnectionLost" CorruptData Kind = "CorruptData" Declined Kind = "Declined" DecryptionFailed Kind = "DecryptionFailed" Denied Kind = "Denied" Duplicated Kind = "Duplicated" Empty Kind = "Empty" EncryptionFailed Kind = "EncryptionFailed" Exceeded Kind = "Exceeded" Exists Kind = "Exists" Expired Kind = "Expired" Fatal Kind = "Fatal" InProgress Kind = "InProgress" Insufficient Kind = "Insufficient" Interrupted Kind = "Interrupted" IsDirectory Kind = "IsDirectory" IsFile Kind = "IsFile" Locked Kind = "Locked" Mismatch Kind = "Mismatch" NotAcceptable Kind = "NotAcceptable" NotAllowed Kind = "NotAllowed" NotDirectory Kind = "NotDirectory" NotEmpty Kind = "NotEmpty" NotExists Kind = "NotExists" NotFile Kind = "NotFile" NotFound Kind = "NotFound" NotImplemented Kind = "NotImplemented" NotRecoverable Kind = "NotRecoverable" NotSupported Kind = "NotSupported" NotValid Kind = "NotValid" OutOfDate Kind = "OutOfDate" OutOfRange Kind = "OutOfRange" Overflowed Kind = "Overflowed" PermissionDenied Kind = "PermissionDenied" QuotaExceeded Kind = "QuotaExceeded" ReadFailed Kind = "ReadFailed" Rejected Kind = "Rejected" Required Kind = "Required" Restricted Kind = "Restricted" Revoked Kind = "Revoked" Temporary Kind = "Temporary" Terminated Kind = "Terminated" Timeout Kind = "Timeout" TooLarge Kind = "TooLarge" TooShort Kind = "TooShort" UserNotFound Kind = "UserNotFound" VerificationFailed Kind = "VerificationFailed" WriteFailed Kind = "WriteFailed" WrongVersion Kind = "WrongVersion" )
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 = ""
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) Error ¶
Error implements error interface and returns the string without any formatting or stack trace. It calls under the hood the string function.
func (Kind) MatchInterface ¶
MatchInterface supports interface behaviour type matching to test for a kind. This allows a package to define a behaviour/kind of an error without importing this package. An error type should implement a function like:
interface{ Fatal() bool }
Where `Fatal` can be any behaviour name like the constants in this package. MatchInterface is 40x slower than function `Match`.
func (Kind) New ¶
New wraps err with the specified Kind. Allows to write an additional message which gets formatted by fmt.Sprintf. It attaches a stack trace.
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 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.