Documentation ¶
Overview ¶
Package errors implements an error type that defines standard interpretable error codes for common error conditions. Errors also contain interpretable severities, so that error-producing operations can be retried in consistent ways. Errors returned by this package can also be chained: thus attributing one error to another. It is inspired by the error packages of both the Upspin and Reflow projects, but generalizes and simplifies these.
Errors are safely serialized with Gob, and can thus retain semantics across process boundaries.
TODO(marius): standardize translating AWS errors into *errors.Error.
Index ¶
- Variables
- func CleanUp(cleanUp func() error, dst *error)
- func CleanUpCtx(ctx context.Context, cleanUp func(context.Context) error, dst *error)
- func E(args ...interface{}) error
- func Is(kind Kind, err error) bool
- func IsTemporary(err error) bool
- func Match(err1, err2 error) bool
- func New(msg string) error
- func Visit(err error, callback func(err error))
- type Error
- type Kind
- type Once
- type Severity
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Separator = ":\n\t"
Separator defines the separation string inserted between chained errors in error messages.
Functions ¶
func CleanUp ¶
CleanUp is defer-able syntactic sugar that calls f and reports an error, if any, to *err. Pass the caller's named return error. Example usage:
func processFile(filename string) (_ int, err error) { f, err := os.Open(filename) if err != nil { ... } defer errors.CleanUp(f.Close, &err) ... }
If the caller returns with its own error, any error from cleanUp will be chained.
func CleanUpCtx ¶
CleanUpCtx is CleanUp for a context-ful cleanUp.
func E ¶
func E(args ...interface{}) error
E constructs a new errors from the provided arguments. It is meant as a convenient way to construct, annotate, and wrap errors.
Arguments are interpreted according to their types:
- Kind: sets the Error's kind
- Severity: set the Error's severity
- string: sets the Error's message; multiple strings are separated by a single space
- *Error: copies the error and sets the error's cause
- error: sets the Error's cause
If an unrecognized argument type is encountered, an error with kind Invalid is returned.
If a kind is not provided, but an underlying error is, E attempts to interpret the underlying error according to a set of conventions, in order:
- If the os.IsNotExist(error) returns true, its kind is set to NotExist.
- If the error is context.Canceled, its kind is set to Canceled.
- If the error implements interface { Timeout() bool } and Timeout() returns true, then its kind is set to Timeout
- If the error implements interface { Temporary() bool } and Temporary() returns true, then its severity is set to at least Temporary.
If the underlying error is another *Error, and a kind is not provided, the returned error inherits that error's kind.
func Is ¶
Is tells whether an error has a specified kind, except for the indeterminate kind Other. In the case an error has kind Other, the chain is traversed until a non-Other error is encountered.
This is similar to the standard library's errors.Is(err, target). That traverses err's chain looking for one that matches target, where target may be os.ErrNotExist, etc. *Error has an explicit Kind instead of an error-typed target, but (*Error).Is defines an error -> Kind relationship to allow interoperability.
func IsTemporary ¶
IsTemporary tells whether the provided error is likely temporary.
func Match ¶
Match tells whether every nonempty field in err1 matches the corresponding fields in err2. The comparison recurses on chained errors. Match is designed to aid in testing errors.
Types ¶
type Error ¶
type Error struct { // Kind is the error's type. Kind Kind // Severity is an optional severity. Severity Severity // Message is an optional error message associated with this error. Message string // Err is the error that caused this error, if any. // Errors can form chains through Err: the full chain is printed // by Error(). Err error }
Error is the standard error type, carrying a kind (error code), message (error message), and potentially an underlying error. Errors should be constructed by errors.E, which interprets arguments according to a set of rules.
Errors may be serialized and deserialized with gob. When this is done, underlying errors do not survive in full fidelity: they are converted to their error strings and returned as opaque errors.
func Recover ¶
Recover recovers any error into an *Error. If the passed-in Error is already an error, it is simply returned; otherwise it is wrapped in an error.
func (*Error) Error ¶
Error returns a human readable string describing this error. It uses the separator defined by errors.Separator.
func (*Error) GobEncode ¶
GobEncode encodes the error for gob. Since underlying errors may be interfaces unknown to gob, Error's gob encoding replaces these with error strings.
func (*Error) Is ¶
Is tells whether e.Kind is equivalent to err.
This implements interoperability with the standard library's errors.Is:
errors.Is(e, errors.Canceled)
works if e.Kind corresponds (in this example, Canceled). This is useful when passing *Error to third-party libraries, for example. Users should still prefer this package's Is for their own tests because it's less prone to error (type checking disallows accidentally swapped arguments).
Note: This match does not recurse into err's cause, if any; see the standard library's errors.Is for how this is used.
type Kind ¶
type Kind int
Kind defines the type of error. Kinds are semantically meaningful, and may be interpreted by the receiver of an error (e.g., to determine whether an operation should be retried).
const ( // Other indicates an unknown error. Other Kind = iota // Canceled indicates a context cancellation. Canceled // Timeout indicates an operation time out. Timeout // NotExist indicates a nonexistent resources. NotExist // NotAllowed indicates a permission failure. NotAllowed // NotSupported indicates an unsupported operation. NotSupported // Exists indicates that a resource already exists. Exists // Integrity indicates an integrity failure. Integrity Unavailable // Invalid indicates that the caller supplied invalid parameters. Invalid // Net indicates a network error. Net // TooManyTries indicates a retry budget was exhausted. TooManyTries // Precondition indicates that a precondition was not met. Precondition // OOM indicates that an OOM condition was encountered. OOM // Remote indicates an error returned by an RPC, as distinct from errors in // the machinery to execute the RPC, e.g. network issues, machine health, // etc. Remote // ResourcesExhausted indicates that there were insufficient resources. ResourcesExhausted )
type Once ¶
type Once struct { // Ignored is a list of errors that will be dropped in Set(). Ignored // typically includes io.EOF. Ignored []error // contains filtered or unexported fields }
Once captures at most one error. Errors are safely set across multiple goroutines.
A zero Once is ready to use.
Example:
var e errors.Once e.Set(errors.New("test error 0"))
Example ¶
package main import ( "fmt" "github.com/Schaudge/grailbase/errors" ) func main() { e := errors.Once{} fmt.Printf("Error: %v\n", e.Err()) e.Set(errors.New("test error 0")) fmt.Printf("Error: %v\n", e.Err()) e.Set(errors.New("test error 1")) fmt.Printf("Error: %v\n", e.Err()) }
Output: Error: <nil> Error: test error 0 Error: test error 0
type Severity ¶
type Severity int
Severity defines an Error's severity. An Error's severity determines whether an error-producing operation may be retried or not.
const ( // Retriable indicates that the failing operation can be safely retried, // regardless of application context. Retriable Severity = -2 // Temporary indicates that the underlying error condition is likely // temporary, and can be possibly be retried. However, such errors // should be retried in an application specific context. Temporary Severity = -1 // Unknown indicates the error's severity is unknown. This is the default // severity level. Unknown Severity = 0 // Fatal indicates that the underlying error condition is unrecoverable; // retrying is unlikely to help. Fatal Severity = 1 )