errors

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2026 License: BSD-3-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package errors is a drop-in replacement for the standard library errors package, providing enhanced error handling with structured attributes, wrapping, joining, and seamless integration with logging frameworks like zap.

This package extends the standard errors functionality while maintaining full compatibility with errors.New, errors.Is, errors.As, and errors.Join.

Key features include:

  • Structured attributes (Attr) for attaching typed metadata to errors
  • Error wrapping with context preservation using Wrap and Wrapf
  • Stack trace capture for debugging
  • JSON serialization support for structured logging
  • Direct integration with popular logging frameworks (zap, etc.)

Basic usage:

err := errors.New("something went wrong")
err = errors.Wrap(err, "failed to process request",
    errors.String("user_id", "123"),
    errors.Int("retry_count", 3))

The Attr system provides type-safe helpers for common types (String, Int, Bool, Time, Duration, etc.) enabling rich error context without losing type information.

Index

Constants

View Source
const (
	// Version is the version of the errors package.
	Version = "0.0.5"
)

Variables

View Source
var (
	// Unwrap returns the result of calling the Unwrap method on err, if err's
	// type contains an Unwrap method returning error.
	// Otherwise, Unwrap returns nil.
	//
	// Unwrap only calls a method of the form "Unwrap() error".
	// In particular Unwrap does not unwrap errors returned by [Join] or [JoinIf].
	Unwrap = stderrors.Unwrap

	// Is reports whether any error in err's tree matches target.
	//
	// The tree consists of err itself, followed by the errors obtained by repeatedly
	// calling its Unwrap() error or Unwrap() []error method. When err wraps multiple
	// errors, Is examines err followed by a depth-first traversal of its children.
	//
	// An error is considered to match a target if it is equal to that target or if
	// it implements a method Is(error) bool such that Is(target) returns true.
	//
	// An error type might provide an Is method so it can be treated as equivalent
	// to an existing error. For example, if MyError defines
	//
	//	func (m MyError) Is(target error) bool { return target == fs.ErrExist }
	//
	// then Is(MyError{}, fs.ErrExist) returns true. See [syscall.Errno.Is] for
	// an example in the standard library. An Is method should only shallowly
	// compare err and the target and not call [Unwrap] on either.
	Is = stderrors.Is

	// As finds the first error in err's tree that matches target, and if one is found, sets
	// target to that error value and returns true. Otherwise, it returns false.
	//
	// The tree consists of err itself, followed by the errors obtained by repeatedly
	// calling its Unwrap() error or Unwrap() []error method. When err wraps multiple
	// errors, As examines err followed by a depth-first traversal of its children.
	//
	// An error matches target if the error's concrete value is assignable to the value
	// pointed to by target, or if the error has a method As(any) bool such that
	// As(target) returns true. In the latter case, the As method is responsible for
	// setting target.
	//
	// An error type might provide an As method so it can be treated as if it were a
	// different error type.
	//
	// As panics if target is not a non-nil pointer to either a type that implements
	// error, or to any interface type.
	As = stderrors.As
)
View Source
var (

	// ErrDepthExceeded is the error returned when the StructuredError is marshaled to a depth
	// greater than MaxDepthMarshal.
	ErrDepthExceeded = New(maxDepthExceeded).WithAttrs(Int(depthKey, maxDepthMarshal))
)
View Source
var (
	// ErrUnmarshalJSON is returned when unmarshaling fails.
	ErrUnmarshalJSON = New("failed to unmarshal JSON")
)

Functions

func Join

func Join(errs ...error) error

Join returns an error that wraps the given errors, any nil error values are discarded. Join returns nil if every value in errs is nil. The error formats depending on logging format otherwise as the concatenation of the strings obtained by calling the Error method of each element of errs, with a newline between each string.

A non-nil error returned by Join implements the Unwrap() []error method.

func JoinIf

func JoinIf(errs ...error) error

JoinIf is similar to Join, but it will only join the errors if the first error is not nil. If the first error is nil, it will return nil, otherwise it will join all the errors. The error formats depending on logging format otherwise as the concatenation of the strings obtained by calling the Error method of each element of errs, with a newline between each string.

A non-nil error returned by JoinIf implements the Unwrap() []error method.

func MaxDepthMarshal

func MaxDepthMarshal() int

MaxDepthMarshal returns the maximum depth to which the StructuredError can be marshaled. If the StructuredError is marshaled to a depth greater than MaxDepthMarshal, it will be truncated at the specified depth during marshaling.

The default value of MaxDepthMarshal is math.MaxInt - 1, which means that the StructuredError can be marshaled to any valid depth.

If MaxDepthMarshal is set to a value less than or equal to 0, the StructuredError cannot be marshaled.

The maximum depth to which the StructuredError can be marshaled is limited by the amount of memory available to the program.

The user can set MaxDepthMarshal to a value greater than the default value to increase the maximum depth to which the StructuredError can be marshaled. However, doing so increases the risk of the program panicking if the StructuredError is too large to be marshaled.

The user can also set MaxDepthMarshal to a value less than the default value to decrease the maximum depth to which the StructuredError can be marshaled. However, doing so increases the risk of the StructuredError being truncated during marshaling.

func SetMaxDepthMarshal

func SetMaxDepthMarshal(depth int)

SetMaxDepthMarshal sets the maximum depth to which the StructuredError can be marshaled. If the StructuredError is marshaled to a depth greater than the specified depth, it will be truncated at the specified depth during marshaling.

The specified depth should be a positive integer.

If the specified depth is less than or equal to 0, the StructuredError cannot be marshaled.

The maximum depth to which the StructuredError can be marshaled is limited by the amount of memory available to the program.

The user can set the maximum depth to which the StructuredError can be marshaled by calling SetMaxDepthMarshal with a positive integer value.

SetMaxDepthMarshal is not thread-safe. It should be called before any StructuredError is marshaled.

Types

type Attr

type Attr struct {
	Value any    `json:"value"`
	Key   string `json:"key"`
	Type  Type   `json:"type"`
}

Attr is a key-value pair with a type.

func Any

func Any(key string, value any) Attr

Any returns an Attr with the given key and value. Useful for logging any type of value or when the provided helper functions are not sufficient. The value can be of any type.

The resulting Attr will have its Type field set to AnyType.

func Bool

func Bool(key string, value bool) Attr

Bool returns an Attr with the given key and value. The value must be a boolean.

The resulting Attr will have its Type field set to BoolType.

func Bools

func Bools(key string, value ...bool) Attr

Bools returns an Attr with the given key and value. The value must be a slice of boolean.

The resulting Attr will have its Type field set to BoolsType.

func Duration

func Duration(key string, value time.Duration) Attr

Duration returns an Attr with the given key and value. The value must be a time.Duration.

The resulting Attr will have its Type field set to DurationType.

The duration will be formatted according to the logger's set format setting.

func Durations

func Durations(key string, value ...time.Duration) Attr

Durations returns an Attr with the given key and value. The value must be a slice of time.Duration.

The resulting Attr will have its Type field set to DurationsType.

The durations will be formatted according to the logger's set format setting.

func Float64

func Float64(key string, value float64) Attr

Float64 returns an Attr with the given key and value. The value must be a float64.

The resulting Attr will have its Type field set to Float64Type.

func Float64s

func Float64s(key string, value ...float64) Attr

Float64s returns an Attr with the given key and value. The value must be a slice of float64.

The resulting Attr will have its Type field set to Float64sType.

func Int

func Int(key string, value int) Attr

Int returns an Attr with the given key and value. The value must be an int.

The resulting Attr will have its Type field set to IntType.

func Int64

func Int64(key string, value int64) Attr

Int64 returns an Attr with the given key and value. The value must be an int64.

The resulting Attr will have its Type field set to Int64Type.

func Int64s

func Int64s(key string, value ...int64) Attr

Int64s returns an Attr with the given key and value. The value must be a slice of int64.

The resulting Attr will have its Type field set to Int64sType.

func Ints

func Ints(key string, value ...int) Attr

Ints returns an Attr with the given key and value. The value must be a slice of int.

The resulting Attr will have its Type field set to IntsType.

func Object

func Object(key string, value ...Attr) Attr

Object returns an Attr with the given key and value. Useful for logging structs and other complex types. The value must be a slice of Attr.

The resulting Attr will have its Type field set to ObjectType.

func String

func String(key, value string) Attr

String returns an Attr with the given key and value. The value must be a string.

The resulting Attr will have its Type field set to StringType.

func Strings

func Strings(key string, value ...string) Attr

Strings returns an Attr with the given key and value. The value must be a slice of string.

The resulting Attr will have its Type field set to StringsType.

func Time

func Time(key string, value time.Time) Attr

Time returns an Attr with the given key and value. The value must be a time.Time.

The resulting Attr will have its Type field set to TimeType.

The time will be formatted according to the logger's set format setting.

func Times

func Times(key string, value ...time.Time) Attr

Times returns an Attr with the given key and value. The value must be a slice of time.Time.

The resulting Attr will have its Type field set to TimesType.

The times will be formatted according to the logger's set format setting.

func Uint64

func Uint64(key string, value uint64) Attr

Uint64 returns an Attr with the given key and value. The value must be an uint64.

The resulting Attr will have its Type field set to Uint64Type.

func Uint64s

func Uint64s(key string, value ...uint64) Attr

Uint64s returns an Attr with the given key and value. The value must be a slice of uint64.

The resulting Attr will have its Type field set to Uint64sType.

func (*Attr) AsMap

func (receiver *Attr) AsMap() map[string]any

AsMap marshals the Attr into a map[string]any If the receiver is nil, it adds a single field to the map[string]any with the key "nil" and the value nilValue.

Otherwise, it will have a single attribute with the key receiver.Key and the value receiver.Value.

func (*Attr) MarshalZerologObject

func (receiver *Attr) MarshalZerologObject(event *zerolog.Event)

MarshalZerologObject implements zerolog.LogObjectMarshaler.

It marshals the Attr into the given zerolog.Event.

If the receiver is nil, it adds a single field to the event with the key nilValue and the value nilValue.

Otherwise, it will have the following attributes:

  • Key: the receiver's key, or nilValue if the receiver is nil.
  • Value: the receiver's value, or ignored if the receiver is nil.

Usage must be with zerolog.Event.Interface or zerolog.Event.Object.

func (*Attr) String

func (receiver *Attr) String() string

String returns the error message as a string.

type LogArrayMarshalerFunc

type LogArrayMarshalerFunc func(*zerolog.Array)

LogArrayMarshalerFunc is a helper type that implements zerolog.LogArrayMarshaler.

func (LogArrayMarshalerFunc) MarshalZerologArray

func (f LogArrayMarshalerFunc) MarshalZerologArray(e *zerolog.Array)

MarshalZerologArray implements zerolog.LogArrayMarshaler.

type LogObjectMarshalerFunc

type LogObjectMarshalerFunc func(*zerolog.Event)

LogObjectMarshalerFunc is a helper type that implements zerolog.LogObjectMarshaler.

func (LogObjectMarshalerFunc) MarshalZerologObject

func (f LogObjectMarshalerFunc) MarshalZerologObject(e *zerolog.Event)

MarshalZerologObject implements zerolog.LogObjectMarshaler.

type MultiUnwrapper

type MultiUnwrapper interface {
	Unwrap() []error
}

MultiUnwrapper represents errors that unwrap to multiple underlying errors.

type SingleUnwrapper

type SingleUnwrapper interface {
	Unwrap() error
}

SingleUnwrapper represents errors that unwrap to a single underlying error.

type StructuredError

type StructuredError struct {
	// Message is the primary error message.
	// It is the only required field.
	// If empty, the error is considered nil with and labeled with "!NILVALUE"
	Message string `json:"message,omitempty"`

	// Attrs contains key-value pairs providing additional context.
	// It is optional.
	// If empty, or nil, it will be marshaled as "[]"
	Attrs []Attr `json:"attrs,omitempty"`

	// Errors contains wrapped underlying errors.
	// It is optional.
	// If empty, or nil, it will be marshaled as "[]"
	Errors []error `json:"errors,omitempty"`

	// Tags contains categorical labels for error classification.
	// It is optional.
	// If empty, or nil, it will be marshaled as "[]"
	Tags []string `json:"tags,omitempty"`

	// Stack contains the stack trace bytes, typically from a panic recovery.
	// It is optional.
	// If empty, or nil, it will be marshaled as "[]"
	Stack []byte `json:"stack,omitempty"`
	// contains filtered or unexported fields
}

StructuredError represents an error with structured metadata including attributes, nested errors, tags, and optional stack traces.

func New

func New(message string) *StructuredError

New creates a StructuredError with the specified message. All other fields (Attrs, Errors, Tags, Stack) are initialized as empty.

func (*StructuredError) AppendErrors

func (receiver *StructuredError) AppendErrors(errors ...error) *StructuredError

AppendErrors adds the given errors after the receiver's existing errors and returns it for chaining. This method mutates the receiver in place.

func (*StructuredError) As

func (receiver *StructuredError) As(target any) bool

As finds the first error in StructuredError's chain that matches the target type, and if one is found, sets the target to its value and returns true.

func (*StructuredError) AsMap

func (receiver *StructuredError) AsMap() map[string]any

AsMap marshals the StructuredError into a map[string]any If the receiver is nil, it adds a single field to the map[string]any with the key "message" and the value nilValue.

Otherwise, it will have the following attributes:

  • Message
  • Tags
  • Attrs
  • Errors
  • Stack.

func (*StructuredError) Error

func (receiver *StructuredError) Error() string

Error returns the error message as a string. Implementation for rhe error built-in interface type for representing an error condition, with the nil value representing no error.

The returned slog.Value will have the following attributes:

  • Message
  • Tags
  • Attrs
  • Errors
  • Stack.

func (*StructuredError) Is

func (receiver *StructuredError) Is(target error) bool

Is reports whether any error in StructuredError's chain matches target. It first checks if the current error matches the target, then checks each error in the Errors slice.

func (*StructuredError) MarshalJSON

func (receiver *StructuredError) MarshalJSON() ([]byte, error)

MarshalJSON marshals the StructuredError into a byte slice. It returns the marshaled byte slice and no error.

The returned []byte will have the following attributes:

  • Message
  • Tags
  • Attrs
  • Errors
  • Stack.

The marshaled data is stored in the StructuredError. If the marshaled data is nil, no fields are added to the StructuredError.

func (*StructuredError) MarshalZerologObject

func (receiver *StructuredError) MarshalZerologObject(event *zerolog.Event)

MarshalZerologObject implements zerolog.LogObjectMarshaler.

It marshals the StructuredError into the given zerolog.Event.

If the receiver is nil, it adds a single field to the event with the key "message" and the value nilValue.

Otherwise, it will have the following attributes:

  • Message
  • Tags
  • Attrs
  • Errors
  • Stack.

Usage must be with zerolog.Event.Interface or zerolog.Event.Object.

func (*StructuredError) PrependErrors

func (receiver *StructuredError) PrependErrors(errors ...error) *StructuredError

PrependErrors adds the given errors before the receiver's existing errors and returns it for chaining. This method mutates the receiver in place.

func (*StructuredError) String

func (receiver *StructuredError) String() string

String returns the error message as a string. It is equivalent to calling Error().

func (*StructuredError) UnmarshalJSON

func (receiver *StructuredError) UnmarshalJSON(data []byte) error

UnmarshalJSON takes a byte slice and unmarshals it into the StructuredError. It returns an error if the unmarshaling fails.

The unmarshaled data is stored in the StructuredError. If the unmarshaling data is nil, no fields are added to the StructuredError.

func (*StructuredError) Unwrap

func (receiver *StructuredError) Unwrap() []error

Unwrap returns the wrapped errors, implementing the MultiUnwrapper interface. This allows StructuredError to work with errors.Is and errors.As.

func (*StructuredError) WithAttrs

func (receiver *StructuredError) WithAttrs(attrs ...Attr) *StructuredError

WithAttrs assigns the given attributes to the receiver and returns it for chaining. This method mutates the receiver in place.

func (*StructuredError) WithErrors

func (receiver *StructuredError) WithErrors(errors ...error) *StructuredError

WithErrors assigns the given errors to the receiver and returns it for chaining.

func (*StructuredError) WithStack

func (receiver *StructuredError) WithStack(stack []byte) *StructuredError

WithStack sets the stack trace on the receiver and returns it for chaining. This is typically used when recovering from a panic to preserve the stack trace. This method mutates the receiver in place.

func (*StructuredError) WithTags

func (receiver *StructuredError) WithTags(tags ...string) *StructuredError

WithTags prepends the given tags to the receiver and returns it for chaining. This method mutates the receiver in place.

type Type

type Type uint8

Type is the type of Attr.

const (
	AnyType Type = iota
	ObjectType
	BoolType
	BoolsType
	TimeType
	TimesType
	DurationType
	DurationsType
	IntType
	IntsType
	Int64Type
	Int64sType
	Uint64Type
	Uint64sType
	Float64Type
	Float64sType
	StringType
	StringsType
)

Type constants define the type of Attr.

Jump to

Keyboard shortcuts

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