goexer

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2023 License: LGPL-2.1 Imports: 9 Imported by: 0

README

goexer - Golang extended errors package

WARNING: API of this package is still unstable. Please wait v1.0.0 before usage.

I like Golang errors extenders but couldn't find a library that is ideal for me.

E.g.

In this project I will try to implement a flexible error type. I still don't know how it should work, but I have several ideas. So, I do not recommend using this library before v1.0.0 will be done.

How it works

Each error has an embedded storage container and stack of errors. At any time you can get any error from stack and check its type, message and where it was raised (function name, file path, line number). You can Wrap() any errors interface compatible errors. Goexer does not full compatible with errors package and can't replace it. Also some functions may works in different style than functions from errors. Each error can be created with ErrorOpts. By default will be used DefaultErrorOpts. Goexer has some helpers for usage with zerolog. You need set zerolog's instance for usage it.

Types

ErrorOpts - options for errors creations.

type ErrorOpts struct {
	Name                 string     // Name (kind) of error. Do not use long strings for better formatting.
	Depth                int        // Depth of stack trace. Increase if need fetch data from previous frame.
	Container            *Container // Use existing container with prefilled data. Use nil for personal container for each error.
	ShowContainerSize    *bool      // Show container size in error message.
	ShowContainerItems   []string   // Show container items in error message (key and value).
	ShowContainerAsZKeys *bool      // Show container items as keys in zerolog, instead of as message.
}

Container - storage for additional fields

type Container struct {
	items map[string]Item
}

Item - type for additional fields. Using inside Container.

type Item struct {
	Value interface{}
	Type  string // Just for better string representation.
	Name  string // Just for better string representation.
}

Error - main type for this package.

In most cases you will works only with this type. This type is compatible with error interface.

type Error struct {
	Message              string // Error message.
	Name                 string // Error name (kind). E.g. NotFound, ... Do not use long strings for better formatting.
	Function             string // Function where error was created.
	File                 string // File with code definition.
	Line                 uint   // Line where error was created.
	Previous             *Error // Previous error.
	Original             error  // Original error if wrap was used for non Error objects.
	Container            *Container
	ShowContainerItems   []string
	ShowContainerSize    bool
	ShowContainerAsZKeys bool // Show container items as keys in zerolog, instead of as message.
}

Examples

Set zerolog's instance.

zlog := zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout})
goexer.SetZLog(&zlog)

Set default for all errors in your project.

t := true
c := goexer.NewContainer().Set("testInt", 10).Set("testString", "zzzz")
goexer.SetDefaultOpts(
    goexer.ErrorOpts{
        Container:            c, // Set one container for all errors.
        ShowContainerSize:    &t, // Show size of container in errors.
        ShowContainerItems:   []string{"testInt", "testString", "testBool"}, // Set fields than sholud be printed in error from container.
        ShowContainerAsZKeys: &t, // Print field as separate keys in zerolog instead of set they as message.
    },
)

Wrap standard error

e := errors.New("stderr")
err := goexer.Wrap(e, "New() w/o opts")

Print error via zerolog Error() event with info about container in message.

err.ShowContainerAsZKeys = false
err.LogError("message1")

Print error as error and as trace with fields as keys in zerolog events.

err.ShowContainerAsZKeys = true
err.LogError("message2")
err.LogTrace("message")

The correct way to create a new error. Use Depth: 1 for getting original .

func ErrNotFound(msg string) *goexer.Error {
	return goexer.New(msg, goexer.ErrorOpts{Depth: 1})
}

err.Set("testBool", true)
ErrNotFound("NotFound").LogTrace()
err.LogFatal()
err.LogError("This message should not be printed after log.Fatal()")

Documentation

Index

Constants

View Source
const (
	BaseErrorName   = "BaseError"
	ErrorTypeString = "*goexer.Error"
)

Variables

This section is empty.

Functions

func Cause

func Cause(err error) error

func CheckErr

func CheckErr(err error)

Check error and log fatal message if not nil.

func IsGoexerError

func IsGoexerError(err error) bool

Check if error is *goexer.Error.

func SetBLog

func SetBLog(log *log.Logger)

Set global basic logger.

func SetDefaultOpts

func SetDefaultOpts(opts ErrorOpts)

SetOpts - set DefaultOptions.

func SetZLog

func SetZLog(log *zerolog.Logger)

Set global zerolog logger.

Types

type Container

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

Container for extended data.

func NewContainer

func NewContainer() *Container

Create new variable of type Container.

func (*Container) Get

func (c *Container) Get(key string) any

Return value of Item.

func (*Container) GetE

func (c *Container) GetE(key string) (any, bool)

Return value of Item with ok status.

func (*Container) GetRaw

func (c *Container) GetRaw(key string) any

Return raw value of Item.

func (*Container) GetRawE

func (c *Container) GetRawE(key string) (any, bool)

Return raw value of Item with ok status.

func (*Container) JSON added in v0.1.2

func (c *Container) JSON() ([]byte, error)

return json representation.

func (*Container) Keys

func (c *Container) Keys() []string

Return all keys of fields inside Container.

func (*Container) Marshaled added in v0.1.2

func (c *Container) Marshaled() Marshaled

Return marshaled representation.

func (*Container) Set

func (c *Container) Set(key string, value interface{}) *Container

Set value for item.

func (*Container) Size

func (c *Container) Size() int

Return count of fields (items) inside Container.

type Error

type Error struct {
	Message              string // Error message.
	Name                 string // Error name (kind). E.g. NotFound, ... Do not use long strings for better formatting.
	Function             string // Function where error was created.
	File                 string // File with code definition.
	Line                 uint   // Line where error was created.
	Previous             *Error // Previous error.
	Original             error  // Original error if wrap was used for non Error objects.
	Container            *Container
	ShowContainerItems   []string
	ShowContainerSize    bool
	ShowContainerAsZKeys bool // Show container items as keys in zerolog, instead of as message.
	AddTraceToError      bool // Add trace messages to error and fatal messages with error level ERROR.
}

func New

func New(msg string, args ...ErrorOpts) *Error

New - create new Error.

func ToError

func ToError(err error) *Error

Convert any error to Error.

func Wrap

func Wrap(prev error, msg string, args ...ErrorOpts) *Error

Wrapp old error to the new one.

func Wrapf

func Wrapf(prev error, format string, args ...interface{}) *Error

Formatted wrap.

func (*Error) Cause

func (e *Error) Cause() error

func (*Error) Error

func (e *Error) Error() string

func (*Error) Format

func (e *Error) Format(s fmt.State, verb rune)

Format - implements extended fmt.Formatter.

func (*Error) Get

func (e *Error) Get(key string) any

func (*Error) GetE

func (e *Error) GetE(key string) (any, bool)

func (*Error) GetRaw

func (e *Error) GetRaw(key string) any

func (*Error) GetRawE

func (e *Error) GetRawE(key string) (any, bool)

func (*Error) Is

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

Support for errors.Is(). Return true if err.Name == e.Name .

func (*Error) LogError

func (e *Error) LogError(msg ...string)

Log with Error log level.

func (*Error) LogFatal

func (e *Error) LogFatal(msg ...string)

Log with fatal log level (with program exit!).

func (*Error) LogTrace

func (e *Error) LogTrace(msg ...string)

Log with trace log level.

func (*Error) LogTraceToEvent

func (e *Error) LogTraceToEvent(event *zerolog.Event, msg ...string)

Log trace to event.

func (*Error) MultiLinePrettyError

func (e *Error) MultiLinePrettyError() string

Pretty string for error in one line style.

func (*Error) OneLinePrettyError

func (e *Error) OneLinePrettyError() string

Pretty string for error in one line style.

func (*Error) Set

func (e *Error) Set(key string, value interface{})

func (*Error) Stack

func (e *Error) Stack() []*Error

Return slice of errors in correct sequence.

func (*Error) StackString

func (e *Error) StackString() string

Return stack as pretty string.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Support errors.Unwrap().

type ErrorOpts

type ErrorOpts struct {
	Name                 string     // Name (kind) of error. Do not use long strings for better formatting.
	Depth                int        // Depth of stack trace. Increase if need fetch data from previous frame.
	Container            *Container // Use existing container with prefilled data. Use nil for personal container for each error.
	ShowContainerSize    *bool      // Show container size in error message.
	ShowContainerItems   []string   // Show container items in error message (key and value).
	ShowContainerAsZKeys *bool      // Show container items as keys in zerolog, instead of as message.
	AddTraceToError      *bool      // Add trace messages to error and fatal messages with error level ERROR.
}

Additional options for New(), Wrap(), ...

var DefaultErrorOpts ErrorOpts = ErrorOpts{
	Name:                 BaseErrorName,
	Depth:                0,
	Container:            nil,
	ShowContainerAsZKeys: nil,
	ShowContainerSize:    nil,
	ShowContainerItems:   nil,
}

type ErrorWrap

type ErrorWrap Error

Allow to print %#v (I need better method, because this brakes type name).

func (*ErrorWrap) Format

func (e *ErrorWrap) Format()

type Item

type Item struct {
	Value interface{}
	Type  string // Just for better string representation.
	Name  string // Just for better string representation.
}

One item inside container.

func (*Item) Get

func (i *Item) Get() any

func (*Item) GetRaw

func (i *Item) GetRaw() interface{}

Return raw, unconverted Value as interface{}.

func (*Item) String

func (i *Item) String() string

Return string representation for Item.

type Marshaled added in v0.1.2

type Marshaled map[string]interface{}

Marshaled representation.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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