Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Recover functions for idiomatic panic redirects #539

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ Error handling:
- [TryCatch](#trycatch)
- [TryWithErrorValue](#trywitherrorvalue)
- [TryCatchWithErrorValue](#trycatchwitherrorvalue)
- [TypedRecover](#typedrecover)
- [Recover0 -> Recover6](#recover0-6)
- [Recover0Error -> Recover6Error](#recover0-6error)
- [Recover0Typed -> Recover6Typed](#recover0-6typed)
- [Recover0ErrorTyped -> Recover6ErrorTyped](#recover0-6errortyped)
- [ErrorsAs](#errorsas)

Constraints:
Expand Down Expand Up @@ -3465,6 +3470,104 @@ ok := lo.TryCatchWithErrorValue(func() error {

[[play](https://go.dev/play/p/8Pc9gwX_GZO)]

### TypedRecover

`TypedRecover` is a helper function that allows a deferred panic recovery as a one-liner with a type parameter for the error interface and the optional inclusion of string panics via the second parameter flag.

```go
func ExampleTypedRecover() (err error) {
defer TypedRecover[error](&err, true)

// Simulating a panic to be returned as error
panic("Unexpected error occurred")
}
```

### Recover{0->6}

The `Recover{0->6}` functions are designed to encapsulate panicking functions, redirecting panic `error` interfaces and `string` types to golang's idiomatic return signature. This is helpful with library functions where an error type has to be returned in addition to the existing return types.

```go
// Example of a library function
func errorOrNil[T any](callback func(string) T) (T, error) {
return lo.Recover1(callback("test"))
}

errorOrNil(func(param string) string {
panic("panicking")
})
// Output: "", "panicking"

errorOrNil(func(param string) string {
return param
})
// Output: "test", nil
```

### Recover{0->6}Error

These functions merge both `Recover{0->6}` and callback error return types into a unified error type. This can be helpful in situations where non-error callback functions are passed to library functions that come with their own error return, making panic the only workaround to pass errors from the callback function to the encapsulating scope.

```go
// A library function with its own error return and a callback without error handling
func externalLibraryFunction(callback func(string) string) (string, error) {
_ = callback("test")
return "", errors.New("final error")
}

lo.Recover1Error(externalLibraryFunction(func(param string) string {
panic("panicking")
}))
// Output: "", "panicking"

lo.Recover1Error(externalLibraryFunction(func(param string) string {
return param
}))
// Output: "", "final error"
```

### Recover{0->6}Typed

The `Recover{0->6}Typed` functions extend the `Recover{0->6}` with an additional type parameter to define the panic error type to be cought, and an optional (variadic) flag to define whether to catch strings as well.

```go
// Example of a library function
func errorOrNil[T any](callback func(string) T) (T, error) {
return lo.Recover1Typed[myError](callback("test"), false)
}

errorOrNil(func(param string) string {
panic("no recovery")
})
// Panic: "no recovery"

errorOrNil(func(param string) string {
panic(erros.New("no recovery"))
})
// Panic: "no recovery"
```

### Recover{0->6}ErrorTyped

The `Recover{0->6}ErrorTyped` functions combine the callback error redirect from `Recover{0->6}Error` and the catch type specification from `Recover{0->6}Typed`.

```go
// Example of a library function
func errorOrNil[T any](callback func() T) (T, error) {
return lo.Recover0ErrorTyped[myError](callback(), true)
}

errorOrNil(func() string {
panic("recovery")
})
// Output: "", "recovery"

errorOrNil(func() string {
return "test"
})
// Output: "test", nil
```

### ErrorsAs

A shortcut for:
Expand Down
Loading