Documentation
¶
Overview ¶
Package errgroup provides utility functions and types for easily recovering from panics.
Index ¶
- func ErrRecover(errI interface{}) error
- func Wrap0(f func() error) func() error
- func Wrap1[T any, F func(T) error](f F) F
- func Wrap1Return1[T any, R any, F func(T) (R, error)](f F) F
- func Wrap2[T1 any, T2 any, F func(T1, T2) error](f F) F
- func Wrap2Return1[T1 any, T2 any, R any, F func(T1, T2) (R, error)](f F) F
- func WrapEgGoWithCustomRecover(f func() error, recovery ErrorHandler) func() error
- func WrapEgGoWithRecover(f func() error) func() error
- type ErrorHandler
- type Group
- type WgErrGroup
- type WgErrGroupWithCustom
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ErrRecover ¶
func ErrRecover(errI interface{}) error
ErrRecover converts a recover() call into an error. Prefer using WrapEgGoWithRecover.
The caller must call recover(), because the stack changes when ErrRecover is called.
See https://play.golang.org/p/FYD2QlmHHO9
Usage:
defer func() {
errR := helpers.ErrRecover(recover())
if errR != nil {
err = errR
}
}()
Example (ErrorWrapping) ¶
ErrorWrapping illustrates how ErrRecover can be used to recover from a panic and convert it into a useful error instead. This allows the caller of the panicking function to regain control and handle the panic as desired.
WrapEgGoWithRecover is simply a wrapper to avoid needing to manually do this wrapping.
package main
import (
"errors"
"fmt"
"github.com/getkalido/panicgroup"
)
var ErrSomethingTerrible error = errors.New("something terrible has happened!")
func main() {
// An example function, which has a chance to panic.
panicFunc := func() (err error) {
defer func() {
// ErrRecover should recover from the panic and convert it to
// an error.
errR := panicgroup.ErrRecover(recover())
if errR != nil {
err = errR
}
}()
panic(ErrSomethingTerrible)
}
err := panicFunc()
if err == nil {
fmt.Println("No error was captured.")
} else {
fmt.Println("The panic was successfully converted into an error.")
}
}
Output: The panic was successfully converted into an error.
func Wrap1Return1 ¶
Wrap1Return1 wraps a function which takes an argument and returns one value (in addition to an error) in panic recovery code.
func Wrap2Return1 ¶
Wrap2Return1 wraps a function which takes two arguments and returns one value (in addition to an error) in panic recovery code.
func WrapEgGoWithCustomRecover ¶
func WrapEgGoWithCustomRecover(f func() error, recovery ErrorHandler) func() error
WrapEgGoWithCustomRecover takes an input function f and wraps it in panic recovery code. If a panic occurs, it is captured and instead converted to a regular error. This error is then passed to recovery, so that recovery can decide what happens to the error.
Example:
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
errChan := make(chan error, 1)
wrappedFunc := panicgroup.WrapEgGoWithCustomRecover(
func() {
panic("AAAAAAAH!")
},
func(err error) error {
select {
case <-ctx.Done():
return ctx.Err()
case errChan<-err:
return err
}
}
)
func WrapEgGoWithRecover ¶
WrapEgGoWithRecover takes an input function f and wraps it in panic recovery code. If a panic occurs, it is captured and instead converted to a regular error.
Example (CustomRecover) ¶
CustomRecover illustrates how WrapEgGoWithRecover can be used to recover from a panic and do something with tthe error before returning.
package main
import (
"errors"
"fmt"
"github.com/getkalido/panicgroup"
)
var ErrSomethingTerrible error = errors.New("something terrible has happened!")
func main() {
errChan := make(chan error, 1)
// An example function, which has a chance to panic.
panicFunc := panicgroup.WrapEgGoWithCustomRecover(
func() (err error) { panic(ErrSomethingTerrible) },
func(err error) error {
errChan <- err
return nil
},
)
err := panicFunc()
if err == nil {
fmt.Println("No error was captured.")
} else {
fmt.Println("The panic was successfully converted into an error.")
}
if <-errChan != nil {
fmt.Println("The panic was successfully sent through a channel.")
}
}
Output: No error was captured. The panic was successfully sent through a channel.
Example (SimplifiedWrapping) ¶
SimplifiedWrapping illustrates how WrapEgGoWithRecover can be used to recover from a panic and convert it into a useful error instead. This allows the caller of the panicking function to regain control and handle the panic as desired.
This simplifies the manual process of adding panic recovery to a block of code.
package main
import (
"errors"
"fmt"
"github.com/getkalido/panicgroup"
)
var ErrSomethingTerrible error = errors.New("something terrible has happened!")
func main() {
// An example function, which has a chance to panic.
panicFunc := panicgroup.WrapEgGoWithRecover(func() (err error) {
panic(ErrSomethingTerrible)
})
err := panicFunc()
if err == nil {
fmt.Println("No error was captured.")
} else {
fmt.Println("The panic was successfully converted into an error.")
}
}
Output: The panic was successfully converted into an error.
Types ¶
type ErrorHandler ¶
ErrorHandler represents a function which performs some action on an error which was converted from a panic.
This function should return as soon as possible if an error group was canceled.
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
func WaitGroup ¶
func WaitGroup() *Group
WaitGroup returns a new instance of WgErrGroup.
WaitGroupWithContext should be preferred, since it is able to cancel execution if one of the goroutines started with Go encounters an error.
func WaitGroupWithContext ¶
WaitGroupWithContext returns a new WgErrGroup and an associated Context derived from ctx.
This function is provided purely for backwards compatibility.
See WithContext for the real implementation.
func WithContext ¶
WithContext returns a new WgErrGroup and an associated Context derived from ctx.
The derived Context is canceled the first time a function passed to Go returns a non-nil error or the first time Wait returns, whichever occurs first.
func (*Group) Go ¶
Go calls the given function in a new goroutine.
The first call to return a non-nil error cancels the group; its error will be returned by Wait.
If the captured panic needs custom handling, use Group.GoCustomRecover instead.
func (*Group) GoCustomRecover ¶
GoCustomRecover calls the given function in a new goroutine. If a panic occurs, the value will be recovered and wrapped with ErrRecover. The resulting error is then passed to recovery and the error returned from recovery will be returned to the Group.
The first call to return a non-nil error cancels the group; its error will be returned by Wait.
If recovery contains blocking operations like sending on a channel, recovery must return when the Group's context is canceled.
If the captured panic just needs to be returned, use Group.Go instead.
type WgErrGroup ¶
WgErrGroup re-implements the core functionality of errgroup.Group, but wrapped in a panic-handling function.
type WgErrGroupWithCustom ¶
type WgErrGroupWithCustom interface {
WgErrGroup
GoCustomRecover(f func() error, errorHandler func(error) error)
}
WgErrGroupWithCustom re-implements the core functionality of errgroup.Group, but wrapped in a panic-handling function. It also adds a way of specifying a custom recovery function, which will execute if a panic is recovered.