errors

package
v0.0.0-...-44c758a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2024 License: Apache-2.0 Imports: 14 Imported by: 12

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

Examples

Constants

This section is empty.

Variables

View Source
var Separator = ":\n\t"

Separator defines the separation string inserted between chained errors in error messages.

Functions

func CleanUp

func CleanUp(cleanUp func() error, dst *error)

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

func CleanUpCtx(ctx context.Context, cleanUp func(context.Context) error, dst *error)

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

func Is(kind Kind, err error) bool

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

func IsTemporary(err error) bool

IsTemporary tells whether the provided error is likely temporary.

func Match

func Match(err1, err2 error) bool

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.

func New

func New(msg string) error

New is synonymous with errors.New, and is provided here so that users need only import one errors package.

func Visit

func Visit(err error, callback func(err error))

Visit calls the given function for every error object in the chain, including itself. Recursion stops after the function finds an error object of type other than *Error.

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

func Recover(err error) *Error

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

func (e *Error) Error() string

Error returns a human readable string describing this error. It uses the separator defined by errors.Separator.

func (*Error) GobDecode

func (e *Error) GobDecode(p []byte) error

GobDecode decodes an error encoded by GobEncode.

func (*Error) GobEncode

func (e *Error) GobEncode() ([]byte, error)

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

func (e *Error) Is(err error) bool

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.

func (*Error) Temporary

func (e *Error) Temporary() bool

Temporary tells whether this error is temporary.

func (*Error) Timeout

func (e *Error) Timeout() bool

Timeout tells whether this error is a timeout error.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns e's cause, if any, or nil. It lets the standard library's errors.Unwrap work with *Error.

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 indicates that a resource was unavailable.
	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
)

func (Kind) Errno

func (k Kind) Errno() (syscall.Errno, bool)

Errno maps k to an equivalent Errno or returns false if there's no good match.

func (Kind) String

func (k Kind) String() string

String returns a human-readable explanation of the error kind k.

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

func (*Once) Err

func (e *Once) Err() error

Err returns the first non-nil error passed to Set. Calling Err is cheap (~1ns).

func (*Once) Set

func (e *Once) Set(err error)

Set sets this instance's error to err. Only the first error is set; subsequent calls are ignored.

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
)

func (Severity) String

func (s Severity) String() string

String returns a human-readable explanation of the error severity s.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL