errorcontext

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2025 License: MIT Imports: 6 Imported by: 0

README

errorcontext

Contextual Error Types for zerolog, zap Loggers & OpenTelemetry Metrics.

Examples

zap
package main

import (
	"errors"

	"go.uber.org/zap"

	zaperrorcontext "github.com/georgepsarakis/errorcontext/backend/zap"
)

var ErrProcessingFailure = errors.New("processing failure")

func main() {
	cfg := zap.NewProductionConfig()
	zapLogger, err := cfg.Build()
	if err != nil {
		panic(err)
	}
	defer zapLogger.Sync()

	err = process()
	if errors.Is(err, ErrProcessingFailure) {
		zapLogger.Warn("something failed",
			zap.Dict("error_context", zaperrorcontext.AsContext(err)...),
			zap.Error(err))
	}
}

func process() error {
	return zaperrorcontext.NewError(
		ErrProcessingFailure,
		zap.String("path", "/a/b"),
		zap.Bool("enabled", true),
	)
}

Documentation

Index

Examples

Constants

View Source
const FieldNamePanicMessage = "panic"
View Source
const FieldNamePanicStackTrace = "stack"

Variables

This section is empty.

Functions

func Collect

func Collect[T error](err error) []T

Collect finds aggregates all errors that match the given target type, within the error chain of err. The resulting slice contains target error instances in reverse order.

func DefaultErrorGenerator

func DefaultErrorGenerator(p Panic) error

Types

type BaseError

type BaseError[T any] struct {
	// contains filtered or unexported fields
}

func NewBaseError

func NewBaseError[T any](originalErr error, initialContext T) *BaseError[T]

func (*BaseError[T]) ContextFields

func (e *BaseError[T]) ContextFields() T

func (*BaseError[T]) Error

func (e *BaseError[T]) Error() string

func (*BaseError[T]) IsPanic

func (e *BaseError[T]) IsPanic() bool

func (*BaseError[T]) IsZero

func (e *BaseError[T]) IsZero() bool

func (*BaseError[T]) MarkAsPanic

func (e *BaseError[T]) MarkAsPanic() *BaseError[T]

func (*BaseError[T]) SetContextFields

func (e *BaseError[T]) SetContextFields(f T)

SetContextFields is a setter that replaces the attached error context.

func (*BaseError[T]) Unwrap

func (e *BaseError[T]) Unwrap() error

Unwrap allows the original error to be resolved by errors.Is & errors.As.

type ErrorGenerator

type ErrorGenerator[T error] func(p Panic) T

type Panic

type Panic struct {
	Message string
	Stack   []string
}

type Recoverer

type Recoverer[T error] struct {
	PanicValueTransform func(r any) (string, error)
	NewErrorFunc        ErrorGenerator[T]
}
Example
package main

import (
	"errors"
	"fmt"

	"go.uber.org/zap"
	"golang.org/x/sync/errgroup"

	"github.com/georgepsarakis/errorcontext"
	zaperrorcontext "github.com/georgepsarakis/errorcontext/backend/zap"
)

func main() {
	cfg := zap.NewProductionConfig()
	zapLogger, err := cfg.Build()
	if err != nil {
		panic(err)
	}
	grp := errgroup.Group{}
	recoverer := errorcontext.Recoverer[*zaperrorcontext.Error]{
		NewErrorFunc: func(p errorcontext.Panic) *zaperrorcontext.Error {
			return zaperrorcontext.FromPanic(p)
		},
	}
	grp.Go(recoverer.WrapFunc(func() error {
		panic("something bad happened")
	}))

	grp.Go(func() error {
		fmt.Println("Hello World")
		return nil
	})
	if err := grp.Wait(); err != nil {
		var ze *zaperrorcontext.Error
		var isPanic bool
		if errors.As(err, &ze) {
			isPanic = ze.IsPanic()
		}
		zapLogger.Warn("something failed",
			zap.Dict("error_context", zaperrorcontext.AsContext(err)...),
			zap.Bool("is_panic", isPanic),
			zap.Error(err))
	}
}
Output:

Hello World

func NewRecoverer

func NewRecoverer[T error](newError ErrorGenerator[T]) Recoverer[T]

func (Recoverer[T]) Format

func (r Recoverer[T]) Format(rv any) Panic

Format transforms an arbitrary value thrown by panic to an error message along with providing the current goroutine stack trace for the panic root cause. If PanicValueTransform is non-nil, an attempt to format the recovered value is performed. If the formatter function returns an error, a fallback approach is used and the failure error message is appended to the standard message template. Note: this method is intended to be public in order to facilitate testing.

func (Recoverer[T]) Wrap

func (r Recoverer[T]) Wrap(fn func() error) (err error)

Wrap allows recovery from panics for the given function. Panics are translated and propagated as errors that can be handled accordingly. Note: unrecovered panics can cause an abnormal program exit.

func (Recoverer[T]) WrapFunc

func (r Recoverer[T]) WrapFunc(fn func() error) func() error

WrapFunc is a convenience wrapper that returns a decorated function, ensuring that panics are converted to error values.

A common use case is to pass the function directly to errgroup.Submit:

grp := errgroup.Group{}
recoverer := errorcontext.Recoverer[error]{
	NewErrorFunc: errorcontext.DefaultErrorGenerator,
}
grp.Go(recoverer.WrapFunc(func() error {
	panic("something bad happened")
}))

Directories

Path Synopsis
backend
zap

Jump to

Keyboard shortcuts

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