errors

package
v0.0.9 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2018 License: MIT Imports: 5 Imported by: 50

README

Errors

A error package that allows you to wrap/unwrap, multi error and inspect error

Issues

Implementation

  • doc/design contains some survey and design choices we made
  • Wrap checks if this is already a WrappedErr, if not, it attach stack
  • MultiErr keep a slice of errors, the thread safe version use mutex and returns copy of slice when Errors is called

Survey

Documentation

Overview

Package errors provides multi error, wrapping and inspection.

Index

Examples

Constants

View Source
const (
	// MultiErrSep is the separator used when returning a slice of errors as single line message
	MultiErrSep = "; "
	// ErrCauseSep is the separator used when returning a error with causal chain as single line message
	ErrCauseSep = ": "
)

Variables

This section is empty.

Functions

func Cause added in v0.0.8

func Cause(err error) error

Cause returns root cause of the error (if any), it stops at the last error that does not implement causer interface. If you want get direct cause, use DirectCause. If error is nil, it will return nil. If error is not wrapped it will return the error itself. error wrapped using https://github.com/pkg/errors also satisfies this interface and can be unwrapped as well.

func DirectCause added in v0.0.8

func DirectCause(err error) error

DirectCause returns the direct cause of the error (if any). It does NOT follow the cause chain all the way down, just the first one (if any), If you want to get root cause, use Cause

func Errorf

func Errorf(format string, args ...interface{}) error

Errorf is New with fmt.Sprintf

func GetType added in v0.0.9

func GetType(err, target error) (matched error, ok bool)

GetType walks the error chain and match by type using reflect, It returns the matched error and match result. You still need to do a type conversion on the returned error.

It calls GetTypeOf to reduce the overhead of calling reflect on target error

func GetTypeOf added in v0.0.9

func GetTypeOf(err error, tpe reflect.Type) (matched error, ok bool)

GetTypeOf requires user to call reflect.TypeOf(exampleErr) as target type. NOTE: for the type matching, we compare equality of reflect.Type directly, Originally we were comparing string, however result from `String()` is not the full path, so x/foo/bar.Encoder can match y/foo/bar.Encoder because we got bar.Encoder for both of them. You can compare interface{} if their underlying type is same and comparable, it is documented in https://golang.org/pkg/reflect/#Type

Related https://github.com/dyweb/gommon/issues/104

func Ignore added in v0.0.9

func Ignore(_ error)

Ignore swallow the error, you should NOT use it unless you know what you are doing (make the lint tool happy) It is inspired by dgraph x/error.go

func Ignore2 added in v0.0.9

func Ignore2(_ interface{}, _ error)

Ignore2 allow you to ignore return value and error, it is useful for io.Writer like functions It is also inspired by dgraph x/error.go

func Is added in v0.0.9

func Is(err, target error) bool

Is walks the error chain and do direct compare. It should be used for checking sentinel errors like io.EOF It returns true on the first match. It returns false when there is no match.

It unwraps both wrapped error and multi error

func IsType added in v0.0.9

func IsType(err, target error) bool

IsType walks the error chain and match by type using reflect. It only returns match result, if you need the matched error, use GetType

It should be used for checking errors that defined their own types, errors created using errors.New, errors.Errof should NOT be checked using this method because they have same type, string if you are using standard library, freshError if you are using gommon/errors

It calls IsTypeOf to reduce the overhead of calling reflect on target error

func IsTypeOf added in v0.0.9

func IsTypeOf(err error, tpe reflect.Type) bool

IsTypeOf requires user to call reflect.TypeOf(exampleErr).String() as the type string

func New

func New(msg string) error

New creates a freshError with stack trace

func PrintFrames added in v0.0.8

func PrintFrames(frames []runtime.Frame)

func Walk added in v0.0.9

func Walk(err error, cb WalkFunc)

Walk traverse error chain and error list, it stops when there is no underlying error or the WalkFunc decides to stop

func Wrap

func Wrap(err error, msg string) error

Wrap creates a wrappedError with stack and set its cause to err.

If the error being wrapped is already a Tracer, Wrap will reuse its stack trace instead of creating a new one. The error being wrapped has deeper stack than where the Wrap function is called and is closer to the root of error. This is based on https://github.com/pkg/errors/pull/122 to avoid having extra interface like WithMessage and WithStack like https://github.com/pkg/errors does.

Wrap returns nil if the error you are trying to wrap is nil, thus if it is the last error checking in a func, you can return the wrap function directly in one line instead of using typical three line error check and wrap.

return errors.Wrap(f.Close(), "failed to close file")

if err := f.Close(); err != nil {
      return errors.Wrap(err, "failed to close file")
}
return nil。。
Example
package main

import (
	"fmt"
	"os"

	"github.com/dyweb/gommon/errors"
)

func main() {
	err := errors.Wrap(os.ErrNotExist, "oops")
	fmt.Println(err)
}
Output:

oops: file does not exist

func Wrapf

func Wrapf(err error, format string, args ...interface{}) error

Wrapf is Wrap with fmt.Sprintf

Types

type ErrorList added in v0.0.9

type ErrorList interface {
	Errors() []error
}

ErrorList is a list of errors that do not fit into the Wrapper model because they are at same level and don't have direct causal relationships. For example, a user request that lacks both username and password can have two parallel errors.

The interface is mainly used for error unwrapping, for create error list, use MultiErr TODO: a better name than ErrorList

type Messenger added in v0.0.9

type Messenger interface {
	Message() string
}

Message return the top level error message without traverse the error chain i.e. when Error() returns `invalid config: file a.json does not exist` Message() returns `invalid config`

type MultiErr

type MultiErr interface {
	error
	fmt.Formatter
	// Append adds error to current selection, it will flatten the error being added if it is also MultiErr
	// It returns true if the appended error is not nil, inspired by https://github.com/uber-go/multierr/issues/21
	Append(error) bool
	// Errors returns errors stored, if no error
	Errors() []error
	// ErrorOrNil returns itself or nil if there are no errors, inspired by https://github.com/hashicorp/go-multierror
	ErrorOrNil() error
	// HasError is ErrorOrNil != nil
	HasError() bool
}

MultiErr is a slice of Error. It has two implementation, NewMultiErr return a non thread safe version, NewMultiErrSafe return a thread safe version using mutex

Example
package main

import (
	"fmt"
	"os"

	"github.com/dyweb/gommon/errors"
)

func main() {
	// TODO: demo the return value of append
	err := errors.NewMultiErr()
	err.Append(os.ErrPermission)
	err.Append(os.ErrNotExist)
	fmt.Println(err.Error())
	fmt.Println(err.Errors())
}
Output:

2 errors; permission denied; file does not exist
[permission denied file does not exist]

func NewMultiErr

func NewMultiErr() MultiErr

NewMultiErr returns a non thread safe implementation

func NewMultiErrSafe

func NewMultiErrSafe() MultiErr

NewMultiErrSafe returns a thread safe implementation which protects the underlying slice using mutex. It returns a copy of slice when Errors is called

type Stack

type Stack interface {
	Frames() []runtime.Frame
}

type Tracer added in v0.0.9

type Tracer interface {
	Stack() Stack
}

Tracer is error with stack trace

type WalkFunc added in v0.0.9

type WalkFunc func(err error) (stop bool)

WalkFunc accepts an error and based on its inspection logic it can tell Walk if it should stop walking the error chain or error list

type Wrapper added in v0.0.8

type Wrapper interface {
	Unwrap() error
}

Wrapper is based on go 2 proposal, it only has an Unwrap method to returns the underlying error

Directories

Path Synopsis
Package errortype defines helper for inspect common error types generated in standard library, so you don't need to import tons of packages for their sentinel error and custom error type.
Package errortype defines helper for inspect common error types generated in standard library, so you don't need to import tons of packages for their sentinel error and custom error type.

Jump to

Keyboard shortcuts

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