errwrap

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jan 21, 2025 License: BSD-2-Clause Imports: 6 Imported by: 1

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As(err error, target any) bool

A re-export of the standard library errors.As

func AsType

func AsType[Err error](err error) (Err, bool)

AsType is equivalient to As and returns the same boolean. Instead of instantiating a struct and passing it by pointer, the type of the error is given as the generic argument It is instantiated and returned.

func Cause

func Cause(err error) error

Cause returns the underlying cause of the error, if possible. Unwrap goes just one level deep, but Cause goes all the way to the bottom If nil is given, it will return nil

func Errors deprecated

func Errors(err error) []error

Deprecated: use Unwraps

func HandleFmtWriteError

func HandleFmtWriteError(handler func(err error))

HandleFmtWriteError handles (rare) errors when writing to fmt.State. It defaults to printing the errors.

func Is

func Is(err, target error) bool

A re-export of the standard library errors.Is

func Join

func Join(errs ...error) error

The same as the standard errors.Join

func Joins

func Joins(errs ...error) []error

The same as errors.Join but returns the array rather than wrapping it. Also uses isNil for a better nil check.

func JoinsG

func JoinsG[T error](errs ...T) []T

A generic form of Joins

func Unwrap

func Unwrap(err error) error

Unwrap uses the Unwrap method to return the next error in the chain or nil. This is the same as the standard errors.Unwrap

func UnwrapGroups

func UnwrapGroups(err error) iter.Seq[error]

UnwrapGroups will unwrap errors visiting each one. An error that defines Unwrap() []error is expanded and traversed This is a depth-first traversal, doing the unwrap first and the expansion second. This can be used for functionality similar to errors.As but it also expands error groups.

Example
err1 := errors.New("error 1")
err2 := errors.New("error 2")
group := Join(err1, err2)
wrapped := fmt.Errorf("wrapped: %w", group)

for e := range UnwrapGroups(wrapped) {
	fmt.Println(e.Error() + "\n")
}
Output:

wrapped: error 1
error 2

error 1
error 2

error 1

error 2

func UnwrapGroupsLevel

func UnwrapGroupsLevel(err error) iter.Seq2[int, error]

UnwrapGroupsStack is similar to UnwrapGroups. It adds a second parameter the level of depth in the error tree.

func Unwraps

func Unwraps(err error) []error

If the error is not nil and an errorGroup or satisfies Unwraps() []error, return its list of errors otherwise return nil

Example
package main

import (
	"errors"
	"fmt"

	"github.com/gregwebs/errors/errwrap"
)

type errorGroup struct {
	errs []error
}

func (eg *errorGroup) Error() string {
	return errors.Join(eg.errs...).Error()
}

func (eg *errorGroup) Unwrap() []error { return eg.errs }

func main() {
	var eg errorGroup
	eg.errs = append(eg.errs, errors.New("error1"))
	eg.errs = append(eg.errs, errors.New("error2"))

	fmt.Println(errwrap.Errors(nil))
	fmt.Println(errwrap.Unwraps(errors.New("test")))
	fmt.Println(errwrap.Unwraps(&eg))
}
Output:

[]
[]
[error1 error2]

func WalkDeep deprecated

func WalkDeep(err error, visitor func(err error) bool) bool

Deprecated: WalkDeep was created before iterators. UnwrapGroups is now preferred for those using Go version >= 1.23. Note that WalkDeep uses the opposite convention for boolean return values compared to golang iterators. WalkDeep does a depth-first traversal of all errors. An error that defines Unwrap() []error is expanded and traversed The visitor function can return true to end the traversal early If iteration is ended early, WalkDeep will return true, otherwise false.

func WalkDeepLevel deprecated

func WalkDeepLevel(err error, visitor func(error, int) bool) bool

Deprecated: WalkDeepLevel was created before iterators. UnwrapGroupsLevel is now preferred for those using Go version >= 1.23. This operates the same as WalkDeep but adds a second parameter to the visitor: the level of depth in the error tree.

func WrapInPlace

func WrapInPlace(err error, wrap func(error) error) bool

Uses ErrorWrapper to wrap in place, if ErrorWrapper is available. Returns true if wrapped in place. Returns false if not wrapped in place, including if the given error is nil.

Example
package main

import (
	"errors"
	"fmt"

	"github.com/gregwebs/errors/errwrap"
)

type inplace struct {
	*errwrap.ErrorWrap
}

func wrapFn(msg string) func(error) error {
	return func(err error) error { return fmt.Errorf("%s: %w", msg, err) }
}

func main() {
	err := inplace{errwrap.NewErrorWrap(errors.New("original error"))}

	// Wrap the error in place
	wrapped := errwrap.WrapInPlace(err, wrapFn("wrapped"))

	// Print the error and whether it was wrapped in place
	fmt.Printf("Wrapped in place: %v\n", wrapped)
	fmt.Printf("Error: %v\n", err)

	// Try with a regular error that doesn't implement ErrorWrapper
	regularErr := errors.New("regular error")
	wrapped = errwrap.WrapInPlace(regularErr, wrapFn("wrapped"))

	// Print the result for regular error
	fmt.Printf("Regular error wrapped in place: %v\n", wrapped)
	fmt.Printf("Regular error: %v\n", regularErr)

}
Output:

Wrapped in place: true
Error: wrapped: original error
Regular error wrapped in place: false
Regular error: regular error

Types

type ErrorUnwrap

type ErrorUnwrap interface {
	error
	Unwrap() error
	// ErrorNoUnwrap is the error message component of the wrapping
	// It will be a prefix of Error()
	// If there is no message in the wrapping then this can return an empty string
	ErrorNoUnwrap() string
}

ErrorUnwrap allows wrapped errors to give just the message of the individual error without any unwrapping.

The existing Error() convention extends that output to all errors that are wrapped. ErrorNoUnwrap() has just the wrapping message without additional unwrapped messages.

Existing Error() definitions look like this:

func (hasWrapped) Error() string { return hasWrapped.message + ": " + hasWrapped.Unwrap().Error() }

An ErrorNoUnwrap() definitions look like this:

func (hasWrapped) ErrorNoUnwrap() string { return hasWrapped.message }

type ErrorWrap

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

ErrorWrap should be included as a pointer. If fulfills the ErrorWrapper interface. This allows for wrapping an inner error without changing the outer type.

func NewErrorWrap

func NewErrorWrap(err error) *ErrorWrap

NewErrorWrap returns a pointer because ErrorWrap should be used as a pointer.

func (*ErrorWrap) Format

func (ew *ErrorWrap) Format(s fmt.State, verb rune)

func (*ErrorWrap) Unwrap

func (ew *ErrorWrap) Unwrap() error

This struct is designed to be used as an embeded error.

func (*ErrorWrap) WrapError

func (ew *ErrorWrap) WrapError(wrap func(error) error)

type ErrorWrapper

type ErrorWrapper interface {
	error
	WrapError(func(error) error)
}

The ErrorWrapper method allows for modifying the inner error while maintaining the same outer type. This is useful for wrapping types that implement an interface that extend errors.

Jump to

Keyboard shortcuts

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