recovery

package module
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2024 License: Apache-2.0 Imports: 8 Imported by: 3

README

Go panic recovery

Helpers for catching panics, including in goroutines. Unify panics as an error, but retain the ability to distinguish it as a PanicError.

Usage

Go routine panic recovery

recovery.Go helps handle goroutine panics and errors. Note that the function given to recovery.Go returns an error, whereas a normal go routine does not.

// This will crash your program
go func() {
	panic("panic")
}

// This will not crash your program
// By default it logs the panic
go recovery.Go(func() error {
	panic("panic")
})

Panics are given to the error handling function as a PanicError. The global error handling function can be set with the variable recovery.ErrorHandler or can be set locally by using GoHandler

errHandler := func(err error) {
	sentry.CaptureException(err)
}

// global
recovery.ErrorHandler = errHandler

// local
recovery.GoHandler(errHandler, func() error {
		panic("panic")
})

Function panic recovery

Recover a panic for a normal function call (not a goroutine) and return the error.

err = recovery.Call(func() error {
	panic("panic")
})

There are also variants that allow the called function to return results in addition to an error: Call1, Call2, Call3. There are two helpers Throw and Throwf for panicing an error that will avoid wrapping it as a PanicError.

Codemod

There are comby rules to help with upgrading existing go routines:

comby -config ../go-recovery/codemod/comby/upgrade.toml -f myfile.go
goimports -w myfile.go
gofmt -w myfile.go

Existing return statements in go routines should be manually changed to return nil.

The upgrades are conservative and will insert function wrapping that is sometimes unnecesssary. In a go statement the arguments to a function, including the method receiver are evaluated immediately. In go fn(x), x is evaluated immediately. The function wrapping with go func(x){}(x) maintains the property of immediate evaluation. If the variable is immutable or copied before changed, then immediate evaluation is unnecessary, but you will need to inspect this manually.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrorHandler func(error) = DefaultErrorHandler

The default ErrorHandler is DefaultErrorHandler

Functions

func Call

func Call(fn func() error) (err error)

Call is a helper function which allows you to easily recover from panics in the given function parameter "fn". If fn returns an error, that will be returned. If a panic occurs, Call will convert it to a PanicError and return it.

func Call1

func Call1[T any](fn func() (T, error)) (T, error)

Same as Call but support returning 1 result in addition to the error.

func Call2

func Call2[T any, U any](fn func() (T, U, error)) (T, U, error)

Same as Call but support returning 2 results in addition to the error.

func Call3

func Call3[T any, U any, V any](fn func() (T, U, V, error)) (T, U, V, error)

Same as Call but support returning 3 results in addition to the error.

func DefaultErrorHandler

func DefaultErrorHandler(err error)

The DefaultErrorHandler prints the error with log.Printf

func Go

func Go(fn func() error)

Go is designed to use as an entry point to a go routine.

go recovery.Go(func() error { ... })

Instead of your program crashing, the panic is converted to a PanicError. The panic or a returned error is given to the global ErrorHandler function. Change the behavior globally by setting the ErrorHandler package variable. Or use GoHandler to set the error handler on a local basis.

func GoHandler

func GoHandler(errorHandler func(err error), fn func() error)

GoHandler is designed to be used when creating go routines to handle panics and errors. Instead of your program crashing, a panic is converted to a PanicError. The panic or a returned error is given to the errorHandler function.

go GoHandler(handler, func() error { ... })

func HTTPMiddleware added in v0.3.0

func HTTPMiddleware(opts MiddlewareOpts) func(http.Handler) http.Handler

func SlogHandler added in v0.3.0

func SlogHandler(opts SlogHandlerOpts) func(context.Context, error)

func Throw

func Throw(err error)

Throw will panic an error as a ThrownError. The error will be returned by Call* functions as a normal error rather than a PanicError. Useful with CallX functions to avoid writing out zero values when prototyping.

func (x int) (int, error) {
	recovery.Call1(func() (int, error) {
		recovery.Throw(err)
	}
}

func Throwf

func Throwf(format string, args ...interface{})

A convenience function for calling Throw(fmt.Errorf(...))

func ToError

func ToError(r interface{}) error

Wrap panic values in a PanicError. nil is returned as nil so this function can be called direclty with the result of recover() A PanicError is returned as is and a ThrownError is returned unwrapped.

Types

type MiddlewareOpts added in v0.3.0

type MiddlewareOpts struct {
	ErrorHandler func(context.Context, error)
}

type PanicError

type PanicError struct {
	Panic interface{}
}

A Panic that was converted to an error.

func (PanicError) Error

func (p PanicError) Error() string

func (PanicError) Format added in v0.3.1

func (p PanicError) Format(s fmt.State, verb rune)

This works with the extended syntax "%+v" for printing stack traces

func (PanicError) Unwrap

func (p PanicError) Unwrap() error

type SlogHandlerOpts added in v0.3.0

type SlogHandlerOpts struct {
	StackPrint StackPrintOption
}

type StackPrintOption added in v0.3.0

type StackPrintOption string
const (
	StackPrintLines      StackPrintOption = "full"
	StackPrintStructured StackPrintOption = "structured"
	StackPrintNone       StackPrintOption = "none"
)

type ThrownError

type ThrownError struct {
	Err error
}

An error that was intentionally thrown via panic Pass it through without wrapping it as a PanicError

func (ThrownError) Error

func (e ThrownError) Error() string

func (ThrownError) Unwrap

func (e ThrownError) Unwrap() error

Jump to

Keyboard shortcuts

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