errors

package module
v0.0.0-...-a3a1322 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2019 License: BSD-3-Clause Imports: 2 Imported by: 0

README

Handle Golang Errors Easier!

This package provides a greatly simplified error management wrapper for Go that behaves somewhat similarly to Dave Cheney's errors package but with far fewer features. If you need stack management or error formatting, consider using his package instead.

destrealm/errors was created somewhat by accident and before I discovered pkg/errors. During the creation of another library, I (re)discovered one of Go's features that is probably its biggest single pain point for large-ish applications and one for which there's been much discussion. That is, of course, error management and the ability--or lack thereof--to include extra data within an error message without ruining the consumer's ability to parse it. For basic errors, this isn't an issue. However, for more complex conditions where upstream consumers may need to know or report additional information to the user or developer, this quickly causes a descent into chaos.

The semantics of this library are somewhat similar to others. It wraps some of the basic functionality of Go's errors, namely errors.New and fmt.Errorf, both of which are provided as references in this library. However, it also defines an ErrorTracer interface which allows for type switching to be done in order to determine the type of the error.

Usage

General usage of this library starts with errors.NewError with an argument containing a string of the error message, e.g.:

var ErrDecoding = errors.NewError("error decoding JSON input")
var ErrEncoding = errors.NewError("error encoding JSON input")

Then, when you encounter a condition where this error is necessary to return, you can include the upstream error as part of your defined error via .Do():

if err := json.Unmarshal(data, map); err != nil {
    return ErrDecoding.Do(err)
}

if b, err := json.Marshal(data); err != nil {
    return ErrEncoding.Do(err)
}

For comparing errors, two methods are provided to determine whether an error is of a particular type (.Is()) or whether it's equal to another error (.Equal()):


var err = errors.New("this is an error")
var ErrExample = errors.NewError("this is an example error")

// ...

if e, ok := someError.(errors.ErrorTracer); ok {
    if e.Is(ErrExample) {
        // True if someError is of the type ErrExample.
    }

    if e.Equal(ErrExample) {
        // True if e is the same as ErrExample. If .Do is called in this
        // example, this will not be true. This compares both ErrExample and
        // the contents of the original error message.
    }
}

To extract and print the original error caught by the code:

if e, ok := err.(errors.ErrorTracer); ok {
    fmt.Println(e.OriginalError())
}

Limitations

Be aware that unlike pkg/errors, this library does not include any method for examining the error stack trace or even the stack of errors. In theory, you can do this yourself by recursively comparing the contents of .OriginalError(), if it implements the ErrorTracer interface then continue, and print out the tree until you hit the base error type (that is, something that only implements .Error()).

This library is intentionally very spartan and is unlikely to grow in extra functionality. We may eventually implement a method of collecting information from the error stack, and we may also provide package-level .Is() and .Equal() functions. We may also implement a deep-equals to determine if the entire error plus its stack is identical, although this may be unlikely.

Part of the rationale for not including an ability to recursively step through the error stack is that most use cases we've encountered with this library tend toward wrapping Go errors one level deep. Rarely have we required nesting ErrorTracer types, and in most cases, calling .OriginalError() will return the first Go error returned. If you follow this convention, you'll likely find limited need for recursively collating errors wrapped by this library.

Patches

Pull requests are welcome. Please be aware that it is the author's intent that this library remain simple and easy to use. As this documentation is also rather bare, if you would like to add anything to make it clearer without sacrificing its conciseness, such requests are also welcome. (This documentation needs work; it was written over the course of about 10 minutes one evening.)

License

destrealm/errors is offered under an NCSA license, which is essentially a 3-clause BSD license combined with the MIT license for clarity. This is the same license used by the LLVM and Clang projects and arguably resolves issues that affect both the BSD and MIT licenses individually. In particular, this license clearly grants you distribution rights for both the software and its associated documentation.

Go here for more information about the NCSA license.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Errorf = fmt.Errorf

Errorf is a convenience reference to fmt.Errorf.

View Source
var New = errors.New

New is a convenience reference to errors.New. This avoids having to import this package with an alias.

Functions

This section is empty.

Types

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error container type. See ErrorTracer for a description of the interface.

func NewError

func NewError(err string) Error

NewError creates a new Error instance with the specified error string. Start here when defining new traceable errors.

func (Error) Add

func (e Error) Add(key string, value string) ErrorTracer

Add includes extra metadata with the error.

func (Error) Do

func (e Error) Do(err error) Error

Do the error. Simplistic, concise, and reasonably descriptive: Returns a copy of the traceable error encapsulating the `error` specified.

func (Error) Equal

func (e Error) Equal(err ErrorTracer) bool

Equal checks whether the two errors are equal to each other. Note that this is a relatively simple text and only compares string contents.

func (Error) Error

func (e Error) Error() string

Error is included to satisfy the error interface.

func (Error) GetMeta

func (e Error) GetMeta() map[string]string

GetMeta returns extra metadata included with the error, if applicable.

func (Error) Is

func (e Error) Is(err error) bool

Is compares whether err is of the same inherited base error as the current error.

func (Error) OriginalError

func (e Error) OriginalError() error

OriginalError returns the error that originally provoked this traceable error; this is the encapsulated error.

type ErrorTracer

type ErrorTracer interface {
	Add(string, string) ErrorTracer
	Do(error) Error
	Equal(ErrorTracer) bool
	Error() string
	GetMeta() map[string]string
	Is(error) bool
	OriginalError() error
}

ErrorTracer defines a "traceable errors" interface. This interface combines the base Error implementation as well as an option for tracing the original error. This package also defines a few helper functions for comparing errors (notably Equal() and Is()). Be aware that this breaks certain expectations regarding how Go's errors should be handled and propogated but provides client code with the option to either a) match or handle the error returned by this package or b) drill down into the underlying cause (i.e. I know an encoding error happened, but what caused it?).

I had written this before discovering pkg/errors, and it's possible this package may be deprecated when (or if) Go2 finally implements something similar.

func Guarantee

func Guarantee(err error) ErrorTracer

Guarantee returns an ErrorTracer regardless of the error's underlying type.

func GuaranteeError

func GuaranteeError(err error, e Error) ErrorTracer

GuaranteeError ensures that the error `err` is of type `e`. If not, it will be wrapped and returned.

func GuaranteeOrNil

func GuaranteeOrNil(err error) ErrorTracer

GuaranteeOrNil guarantees the return of an ErrorTracer or nil, depending on the original type of err.

Jump to

Keyboard shortcuts

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