panicgroup

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 6, 2025 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package errgroup provides utility functions and types for easily recovering from panics.

Index

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 Wrap0

func Wrap0(f func() error) func() error

Wrap0 wraps a function which takes no arguments in panic recovery code.

func Wrap1

func Wrap1[T any, F func(T) error](f F) F

Wrap1 wraps a function which takes one argument in panic recovery code.

func Wrap1Return1

func Wrap1Return1[T any, R any, F func(T) (R, error)](f F) F

Wrap1Return1 wraps a function which takes an argument and returns one value (in addition to an error) in panic recovery code.

func Wrap2

func Wrap2[T1 any, T2 any, F func(T1, T2) error](f F) F

Wrap2 wraps a function which takes two arguments in panic recovery code.

func Wrap2Return1

func Wrap2Return1[T1 any, T2 any, R any, F func(T1, T2) (R, error)](f F) F

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

func WrapEgGoWithRecover(f func() error) func() error

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

type ErrorHandler func(error) error

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

func WaitGroupWithContext(ctx context.Context) (*Group, context.Context)

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

func WithContext(ctx context.Context) (*Group, context.Context)

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

func (g *Group) Go(f func() error)

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

func (g *Group) GoCustomRecover(f func() error, recovery func(error) error)

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.

func (*Group) Wait

func (g *Group) Wait() error

Wait blocks until all function calls from the Go method have returned, then returns the first non-nil error (if any) from them.

type WgErrGroup

type WgErrGroup interface {
	Go(func() error)
	Wait() error
}

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.

Jump to

Keyboard shortcuts

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