erc

package
v0.14.1 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2026 License: Apache-2.0 Imports: 8 Imported by: 51

Documentation

Overview

Package erc provides a simple/fast error aggregation tool for collecting and aggregating errors. The tools are compatible with go's native error wrapping, and are generally safe for use from multiple goroutines, so can simplify error collection patterns in worker-pool patterns.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromIterator added in v0.14.1

func FromIterator[T any](seq iter.Seq2[T, error]) ([]T, error)

FromIterator consumes an iterator sequence and returns only the values that were successfully produced (without errors). All errors encountered during iteration are aggregated using an error Collector. If any errors occur, both a non-nil slice of successful values AND a non-nil aggregated error are returned, allowing partial results to be recovered.

Use FromIterator when you want to skip failed values but continue processing and collect all errors for later inspection.

func FromIteratorAll added in v0.14.1

func FromIteratorAll[T any](seq iter.Seq2[T, error]) ([]T, error)

FromIteratorAll consumes an iterator sequence and returns ALL values produced, regardless of whether they had associated errors. Unlike FromIterator, this function includes values even when an error occurred for that iteration. All errors are aggregated using an error Collector. If any errors occur, both a non-nil slice (containing all values) AND a non-nil aggregated error are returned.

Use FromIteratorAll when you need to collect every value from the sequence, even those that produced errors, while still tracking all errors that occurred.

func FromIteratorUntil added in v0.14.1

func FromIteratorUntil[T any](seq iter.Seq2[T, error]) ([]T, error)

FromIteratorUntil consumes an iterator sequence and stops immediately upon encountering the first error. Unlike FromIterator and FromIteratorAll, this function does NOT aggregate errors - it returns the first error encountered directly and stops iteration. All successfully processed values before the error are returned in the slice. If no errors occur, returns the complete slice with a nil error.

Use FromIteratorUntil when you want fail-fast behavior and don't need to continue processing after the first error.

func Invariant added in v0.14.0

func Invariant(err error, args ...any)

Invariant raises an invariant error if the error is not nil. The content of the panic contains both the ers.ErrInvariantViolation, and optional additional annotations.

func InvariantOk added in v0.14.0

func InvariantOk(condition bool, args ...any)

InvariantOk raises an invariant error when the condition is false. Optional args annotate the error that is passed to panic. The panic is always rooted in ers.ErrInvariantViolation.

func Join added in v0.10.0

func Join(errs ...error) error

Join takes a slice of errors and converts it into an *erc.List typed error. This operation has several advantages relative to using errors.Join(): if you call erc.Join repeatedly on the same error set of errors the resulting error is convertable.

func JoinSeq added in v0.14.0

func JoinSeq(errs iter.Seq[error]) error

JoinSeq takes an iterator sequence of errors and aggregates them into a single error. This operation is similar to Join but accepts an iter.Seq[error] instead of a variadic slice. Nil errors are filtered out, and if all errors are nil, JoinSeq returns nil. If only one non-nil error exists, it is returned directly. Otherwise, a *Collector is returned containing all non-nil errors.

The resulting error is compatible with errors.Is and errors.As for introspecting the constituent errors.

func Must added in v0.14.0

func Must[T any](arg T, err error) T

Must wraps a function that returns a value and an error, and converts the error to a panic.

func MustOk added in v0.14.0

func MustOk[T any](out T, ok bool) T

MustOk raises an invariant violation if the ok value is false, and returns the first value if the second value is ok. Useful as in:

out := erc.MustOk(func() (string, bool) { return "hello world", true })

func NewInvariantError added in v0.13.0

func NewInvariantError(args ...any) error

NewInvariantError returns an error that is either ers.ErrInvariantViolation, or an error wrapped with ers.ErrInvariantViolation.

func ParsePanic added in v0.12.0

func ParsePanic(r any) error

ParsePanic converts a panic to an error, if it is not, and attaching the ErrRecoveredPanic error to that error. If no panic is detected, ParsePanic returns nil.

Types

type Collector

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

Collector is a simplified version of the error collector in github.com/tychoish/emt. The collector is thread safe and aggregates errors which can be resolved as a single error. The constituent errors (and flattened, in the case of wrapped errors), are an *erc.List object, which can be introspected as needed.

Internally Collectors use a linked-list implementation to avoid pre-allocation concerns and limitations.

func AsCollector added in v0.12.0

func AsCollector(err error) *Collector

AsCollector takes an error and converts it to a list if possible, if the error is an erc.List then this is a passthrough, and errors that implement {Unwind() []error} or {Unwrap() []error}, though preferring Unwind, are added individually to the list.

For errors that provide the Unwind/Unwrap method, if these methods return empty slices of errors, then AsCollector will return nil.

func (*Collector) As added in v0.12.0

func (ec *Collector) As(target any) bool

As supports the errors.As() operation to access.

func (*Collector) Check

func (ec *Collector) Check(fut func() error)

Check executes a simple function and if it returns an error, adds it to the collector, primarily for use in defer statements.

func (*Collector) Err added in v0.12.0

func (ec *Collector) Err() error

Err returns the contents of the collector, as an error. Provides the same functionality as Resolve(). The underlying error is of type *erc.Collector, or nil if there have been no errors added. As a special case, single errors are unwrapped and returned directly.

func (*Collector) Error added in v0.12.0

func (ec *Collector) Error() string

Error implements the error interface, and renders an error message that includes all of the constituent errors.

func (*Collector) Errorf added in v0.13.0

func (ec *Collector) Errorf(tmpl string, args ...any)

Errorf constructs an error, using fmt.Errorf, and adds it to the collector.

func (*Collector) From added in v0.14.0

func (ec *Collector) From(seq iter.Seq[error])

From adds all non-nil error values from the iterator sequence to the error collector. Nil errors in the sequence are automatically filtered out and ignored. This method is thread-safe and can be called concurrently with other Collector methods.

The method uses irt.KeepErrors to filter the sequence, ensuring only non-nil errors are added to the collector.

func (*Collector) If added in v0.13.0

func (ec *Collector) If(cond bool, val error)

If adds the error to the collector when the condition is true, and ignores it otherwise.

func (*Collector) Is added in v0.12.0

func (ec *Collector) Is(target error) bool

Is supports the errors.Is() function and returns true if any of the errors in the collector OR their ancestors are the target error.

func (*Collector) Iterator

func (ec *Collector) Iterator() iter.Seq[error]

Iterator returns an iterator over the errors in the collector. The oldest or earliest errors collected appear first in the iteration order.

func (*Collector) Join added in v0.13.0

func (ec *Collector) Join(errs ...error)

Join appends one or more errors to the collectors. Nil errors are always omitted from the collector.

func (*Collector) Len added in v0.10.0

func (ec *Collector) Len() int

Len reports on the total number of non-nil errors collected. The count tracks a cached size of the *erc.List, giving Len() stable performance characteristics; however, because the Collector unwrap and merge Stack and other { Unwrap() []error } errors, Len is not updated beyond the current level. In this way Len really reports "height," but this is the same for the top level.

func (*Collector) New added in v0.13.0

func (ec *Collector) New(val string)

New adds an error to the collector using the provided string as its value. The error is an ers.Error object.

func (*Collector) Ok added in v0.10.9

func (ec *Collector) Ok() bool

Ok returns true if there are any underlying errors, and false otherwise.

func (*Collector) Push added in v0.12.0

func (ec *Collector) Push(err error)

Push collects an error if that error is non-nil.

func (*Collector) Recover

func (ec *Collector) Recover()

Recover can be used in a defer to collect a panic and add it to the collector.

func (*Collector) Resolve

func (ec *Collector) Resolve() error

Resolve returns an error of type *erc.Collector, or nil if there have been no errors added. As a special case, single errors are unwrapped and returned directly.

func (*Collector) SetFilter added in v0.12.0

func (ec *Collector) SetFilter(erf Filter)

SetFilter sets (or overrides) the current filter on the collector. Errors errors collected by the filter are passed to the filter function. Filters will not receive nil errors.

func (*Collector) Unwrap added in v0.12.0

func (ec *Collector) Unwrap() []error

Unwrap returns all of the constituent errors held by the collector. The implementation of errors.Is and errors.As mean that this method is not called for either of those functions, you can use this director or with ers.Unwind() to get all errors in a slice.

Internally collectors use a linked list implementation, so Unwrap() requires building the slice.

func (*Collector) When added in v0.12.0

func (ec *Collector) When(cond bool, val string)

When is a helper function, typically useful for improving the readability of validation code. If the condition is true, then When creates an error with the string value and adds it to the Collector.

func (*Collector) Whenf added in v0.12.0

func (ec *Collector) Whenf(cond bool, val string, args ...any)

Whenf conditionally creates and adds an error to the collector, as When, and with a similar use case, but permits Sprintf/Errorf formating.

func (*Collector) WithRecover added in v0.12.0

func (ec *Collector) WithRecover(fn func())

WithRecover calls the provided function, collecting any panic and converting it to an error// that is added to the collector.

func (*Collector) WithRecoverHook added in v0.12.0

func (ec *Collector) WithRecoverHook(hook func())

WithRecoverHook catches a panic and adds it to the error collector and THEN runs the specified hook if. If there was no panic, this function is a noop, and the hook never executes. Nil hooks are also a noop. Run WithRecoverHook in defer statements.

func (*Collector) Wrap added in v0.12.0

func (ec *Collector) Wrap(err error, annotation string)

Wrap adds an annotated error to the Collector, IF the wrapped error is non-nil: nil errors are always a noop. If there is no annotation, the error is added directly. Errors are annotated using fmt.Errorf and the %w token.

func (*Collector) Wrapf added in v0.12.0

func (ec *Collector) Wrapf(err error, tmpl string, args ...any)

Wrapf adds an annotated error to the collector IF the error is non-nil: nil errors make Wrapf a noop. Errors are annotated using fmt.Errorf and the %w token.

type Filter added in v0.12.0

type Filter func(error) error

Filter provides a way to process error messages, either to remove errors, reformulate, or annotate errors.

func NewFilter added in v0.12.0

func NewFilter() Filter

NewFilter produces a filter that always returns the original error.

func (Filter) Apply added in v0.12.0

func (erf Filter) Apply(err error) error

Apply runs the Filter on all non-nil errors. nil Filters become noops. This means for all non-Force filters, nil you can use uninitialized filters as the "base" of a chain, as in:

var erf Filter
err = erf.Join(f1, f1, f3).Apply(err)

While Apply will not attempt to execute a nil Filter, it's possible to call a nil Filter added with Next() or where the filter is called directly.

func (Filter) Join added in v0.12.0

func (erf Filter) Join(filters ...Filter) Filter

Join returns a filter that applies itself, and then applies all of the filters passed to it sequentially. If an filter returns a nil error immediately, execution stops as this is a short circuit operation.

func (Filter) Next added in v0.12.0

func (erf Filter) Next(next Filter) Filter

Next calls the "next" filter on the result of the first filter. Both Filters are called all errors, including nil errors.

func (Filter) Only added in v0.12.0

func (erf Filter) Only(inclusions ...error) Filter

Only takes filters errors, propagating only errors that are (in the sense of errors.Is) in the inclusion list. All other errors are returned as nil and are not propagated.

func (Filter) Remove added in v0.12.0

func (erf Filter) Remove(check func(error) bool) Filter

Remove returns nil whenever the check function returns true. Use this to remove errors from the previous Filter (e.g. erf).

func (Filter) Then added in v0.12.0

func (erf Filter) Then(after Filter) Filter

Then functions like Join, but for a single function. The "after" function is called on the results of the first function are non-nil. The first function is only called if the input error is non-nil. Nil filters are ignored.

func (Filter) Without added in v0.12.0

func (erf Filter) Without(exclusions ...error) Filter

Without produces a filter that only returns errors that do NOT appear in the exclusion list. All other errors are takes an error and returns nil if the error is nil, or if the error (or one of its wrapped errors,) is in the exclusion list.

func (Filter) WithoutContext added in v0.12.0

func (erf Filter) WithoutContext() Filter

WithoutContext removes only context cancellation and deadline exceeded/timeout errors. All other errors are propagated.

func (Filter) WithoutTerminating added in v0.12.0

func (erf Filter) WithoutTerminating() Filter

WithoutTerminating removes all terminating errors (e.g. io.EOF, ErrCurrentOpAbort, ErrContainerClosed). Other errors are propagated.

Jump to

Keyboard shortcuts

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