zerr

package module
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2022 License: MIT Imports: 9 Imported by: 0

README

zerr

Error wrapper that allows adding zap fields to an error, and fetching them at a later stage

Installation

To install, run:

go get gitlab.com/yzzyx/zerr

Wrapping errors

To wrap an error with additional field:

// Add int field to error
err = zerr.Wrap(err).WithInt("int-field", 15)
// or, using zap directly
err = zerr.Wrap(err, zap.Int("int-field", 15))

You can add any number of fields the the error:

// Add multiple fields to error
err = zerr.Wrap(err).WithInt("int-field", 15).WithString("query", query).WithAny("obj", obj)

// or, using zap directly
err = zerr.Wrap(err, zap.Int("int-field", 15), zap.String("query", query), zap.Any("obj", obj))

By default, a stacktrace is added when an error is wrapped. To avoid this behaviour call zerr.WrapNoStack() instead. This allows for a specific error to be wrapped without a stacktrace, regardless of the setting DefaultAddStacktrace.

// Do not include a stacktrace
err = zerr.WrapNoStack(err)

// WrapNoStack can also take extra fields, just like Wrap()
err = zerr.WrapNoStack(err, zap.Int("int-field", 15), zap.String("query", query))
// or be chained
err = zerr.WrapNoStack(err).WithInt("int-field", 15).WithString("query", query)

Note that Wrap will not add additional stacktraces if one was already included in the error. If additional stacktraces should be included, it must be specified explicitly, by calling zerr.Wrap with a field created with zap.Stack()

Errors can be wrapped multiple times. All added fields, regardless of level, will be extracted.

Sugared wrapping

For ease of use, sugared versions are availble of the Wrap()-functions, which expects an error followed by a list of alternating string keynames and values to be passed as arguments.

err := zerr.Sugar(err, "fieldname1", intvalue1, "fieldname2", stringvalue2)

// which is equal to:
err = zerr.Wrap(err).WithInt("fieldname1", intvalue1).WithString("fieldname2", stringvalue2)

A corresponding function zerr.SugarNoStack is available to wrap an error without a stack trace

Logging HTTP requests

The zerr package contains a wrapper Field for conveniently logging HTTP requests.

zerr.Wrap(err).WithRequest("request", r))

Adding fields to errors

It is possible to create a new error with additional fields with the methods WithInt(), WithString(), WithAny() etc. Using the WithField() method, a zap Field can be wrapped directly.

ze1 := zerr.Wrap(err)
ze2 := ze.WithField(zap.Int("test", 1))

Using with zap

Using zerr allows capturing errors with additional context information deep down in the call stack, and the returning this error back up to a level were logging can take place, while still having access to the context and stacktrace to where the error actually occurred.


func broken(fname string) error {
    _, err := os.Open(fname)
    if err != nil {
        return zerr.Wrap(err, zap.String("filename", fname))
    }
    // do something else
    return nil
}   

func main() {
    
    logger := zap.NewDevelopment()
    
    err = broken("/this-file-does-not-exist")
    if err != nil {
    	// Log error to logger, using the intial error as message
    	zerr.Wrap(err).LogError(logger)
    	// Or, if we want to add additional fields:
    	zerr.Wrap(err).WithInt("extra", 15)).LogError(logger)
    	// Logging with different level
    	zerr.Wrap(err).WithInt("extra", 15)).LogInfo(logger)
        // Adding HTTP request info
    	zerr.Wrap(err).WithRequest(r).LogError(logger)
    	
    	// Or, to call logger with a specific message:
        logger.Error("error calling broken", zerr.Fields(err)...)
    }
    
}

Reading errors

In order to extract the field data from errors, use the function zerr.Fields.

// Extract any additional fields from error and log
if err != nil {
    zap.Error("something went wrong", zerr.Fields(err)...)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cause

func Cause(err error) error

Cause returns the original cause for an error, if available.

func FieldRequest

func FieldRequest(key string, r *http.Request) zap.Field

FieldRequest converts a http request to a zap request, which is compatible with the zap ObjectMarshaler interface

func Fields

func Fields(err error) []zap.Field

Fields returns any/all fields that are attached to an error

Types

type Error

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

Error is the type used to wrap other errors with additional fields

func Sugar

func Sugar(err error, args ...interface{}) *Error

Sugar is a sugared version of the 'Wrap' function above. It allows the user to add fields without using strongly typed fields, e.g. errors.Wraps(err, "key-1", 12, "key-2", "some string", "key-3", value)

func SugarNoStack

func SugarNoStack(err error, args ...interface{}) *Error

SugarNoStack is exactly like the 'Sugar' function but without an additional stacktrace

func Wrap

func Wrap(err error, fields ...zap.Field) *Error

Wrap adds zap fields to an error

func WrapNoStack

func WrapNoStack(err error, fields ...zap.Field) *Error

WrapNoStack wraps error with fields, but always excludes the stack trace

func (*Error) Cause

func (e *Error) Cause() error

Cause returns the cause of this error Note that Unwrap should be used, this is included for compatibility with pkg/errors

func (*Error) Error

func (e *Error) Error() string

Error makes us implement the standard error interface

func (*Error) Fields

func (e *Error) Fields() []zap.Field

Fields returns all fields attached to this error, and all fields attached to previous errors

func (*Error) LogDPanic

func (e *Error) LogDPanic(logger *zap.Logger)

LogDPanic logs an Error with DPanic level to a given zap logger

func (*Error) LogDebug

func (e *Error) LogDebug(logger *zap.Logger)

LogDebug logs an Error with Debug level to a given zap logger

func (*Error) LogError

func (e *Error) LogError(logger *zap.Logger)

LogError logs an Error with Error level to a given zap logger

func (*Error) LogFatal

func (e *Error) LogFatal(logger *zap.Logger)

LogFatal logs an Error with Fatal level to a given zap logger

func (*Error) LogInfo

func (e *Error) LogInfo(logger *zap.Logger)

LogInfo logs an Error with Info level to a given zap logger

func (*Error) LogPanic

func (e *Error) LogPanic(logger *zap.Logger)

LogPanic logs an Error with Panic level to a given zap logger

func (*Error) LogWarn

func (e *Error) LogWarn(logger *zap.Logger)

LogWarn logs an Error with Warn level to a given zap logger

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the cause of this error

func (*Error) WithAny

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

Standard zap-fields

func (*Error) WithArray

func (e *Error) WithArray(key string, val zapcore.ArrayMarshaler) *Error

func (*Error) WithBinary

func (e *Error) WithBinary(key string, val []byte) *Error

func (*Error) WithBool

func (e *Error) WithBool(key string, val bool) *Error

func (*Error) WithBools

func (e *Error) WithBools(key string, bs []bool) *Error

func (*Error) WithByteString

func (e *Error) WithByteString(key string, val []byte) *Error

func (*Error) WithByteStrings

func (e *Error) WithByteStrings(key string, bss [][]byte) *Error

func (*Error) WithComplex128

func (e *Error) WithComplex128(key string, val complex128) *Error

func (*Error) WithComplex128s

func (e *Error) WithComplex128s(key string, nums []complex128) *Error

func (*Error) WithComplex64

func (e *Error) WithComplex64(key string, val complex64) *Error

func (*Error) WithComplex64s

func (e *Error) WithComplex64s(key string, nums []complex64) *Error

func (*Error) WithDuration

func (e *Error) WithDuration(key string, val time.Duration) *Error

func (*Error) WithDurations

func (e *Error) WithDurations(key string, ds []time.Duration) *Error

func (*Error) WithError

func (e *Error) WithError(err error) *Error

func (*Error) WithErrors

func (e *Error) WithErrors(key string, errs []error) *Error

func (*Error) WithField

func (e *Error) WithField(f zap.Field, additionalFields ...zap.Field) *Error

WithField creates a new Error instance, with one or more fields added. Note that this is equivalent to calling WrapNoStack(err, f)

func (*Error) WithFloat32

func (e *Error) WithFloat32(key string, val float32) *Error

func (*Error) WithFloat32s

func (e *Error) WithFloat32s(key string, nums []float32) *Error

func (*Error) WithFloat64

func (e *Error) WithFloat64(key string, val float64) *Error

func (*Error) WithFloat64s

func (e *Error) WithFloat64s(key string, nums []float64) *Error

func (*Error) WithInt

func (e *Error) WithInt(key string, val int) *Error

func (*Error) WithInt16

func (e *Error) WithInt16(key string, val int16) *Error

func (*Error) WithInt16s

func (e *Error) WithInt16s(key string, nums []int16) *Error

func (*Error) WithInt32

func (e *Error) WithInt32(key string, val int32) *Error

func (*Error) WithInt32s

func (e *Error) WithInt32s(key string, nums []int32) *Error

func (*Error) WithInt64

func (e *Error) WithInt64(key string, val int64) *Error

func (*Error) WithInt64s

func (e *Error) WithInt64s(key string, nums []int64) *Error

func (*Error) WithInt8

func (e *Error) WithInt8(key string, val int8) *Error

func (*Error) WithInt8s

func (e *Error) WithInt8s(key string, nums []int8) *Error

func (*Error) WithInts

func (e *Error) WithInts(key string, nums []int) *Error

func (*Error) WithNamedError

func (e *Error) WithNamedError(key string, err error) *Error

func (*Error) WithNamespace

func (e *Error) WithNamespace(key string) *Error

func (*Error) WithObject

func (e *Error) WithObject(key string, val zapcore.ObjectMarshaler) *Error

func (*Error) WithReflect

func (e *Error) WithReflect(key string, val interface{}) *Error

func (*Error) WithRequest

func (e *Error) WithRequest(r *http.Request) *Error

WithRequest adds information about a http request to the given error. This is a convenience function that performs the same task as calling

err.WithField(zerr.FieldRequest("request", r))

or

WrapNoStack(err, zerr.FieldRequest("request", r))

func (*Error) WithSkip

func (e *Error) WithSkip() *Error

func (*Error) WithStack

func (e *Error) WithStack(key string) *Error

func (*Error) WithString

func (e *Error) WithString(key string, val string) *Error

func (*Error) WithStringer

func (e *Error) WithStringer(key string, val fmt.Stringer) *Error

func (*Error) WithStrings

func (e *Error) WithStrings(key string, ss []string) *Error

func (*Error) WithTime

func (e *Error) WithTime(key string, val time.Time) *Error

func (*Error) WithTimes

func (e *Error) WithTimes(key string, ts []time.Time) *Error

func (*Error) WithUint

func (e *Error) WithUint(key string, val uint) *Error

func (*Error) WithUint16

func (e *Error) WithUint16(key string, val uint16) *Error

func (*Error) WithUint16s

func (e *Error) WithUint16s(key string, nums []uint16) *Error

func (*Error) WithUint32

func (e *Error) WithUint32(key string, val uint32) *Error

func (*Error) WithUint32s

func (e *Error) WithUint32s(key string, nums []uint32) *Error

func (*Error) WithUint64

func (e *Error) WithUint64(key string, val uint64) *Error

func (*Error) WithUint64s

func (e *Error) WithUint64s(key string, nums []uint64) *Error

func (*Error) WithUint8

func (e *Error) WithUint8(key string, val uint8) *Error

func (*Error) WithUint8s

func (e *Error) WithUint8s(key string, nums []uint8) *Error

func (*Error) WithUintptr

func (e *Error) WithUintptr(key string, val uintptr) *Error

func (*Error) WithUintptrs

func (e *Error) WithUintptrs(key string, us []uintptr) *Error

func (*Error) WithUints

func (e *Error) WithUints(key string, nums []uint) *Error
type Header http.Header

Header is a wrapper around http.Header that implements zapcore.ObjectMarshaler

func (Header) MarshalLogObject

func (h Header) MarshalLogObject(enc zapcore.ObjectEncoder) (err error)

MarshalLogObject encodes headers with a zapcore.ObjectEncoder

type Request

type Request struct {
	*http.Request
}

Request is a wrapper around http.Request that implements zapcore.ObjectMarshaler

func (*Request) MarshalLogObject

func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error

MarshalLogObject encodes request with a zapcore.ObjectEncoder

type StringArray

type StringArray []string

StringArray is an array of strings that implements zapcore.ArrayMarshaler

func (StringArray) MarshalLogArray

func (a StringArray) MarshalLogArray(enc zapcore.ArrayEncoder) error

MarshalLogArray encodes an array of strings with a zapcore.ArrayEncoder

type URLValues

type URLValues url.Values

URLValues is a wrapper around url.Values that implements zapcore.ObjectMarshaler

func (URLValues) MarshalLogObject

func (values URLValues) MarshalLogObject(enc zapcore.ObjectEncoder) (err error)

MarshalLogObject encodes url values with a zapcore.ObjectEncoder

Jump to

Keyboard shortcuts

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