feat: adding ErrorsAs

This commit is contained in:
Samuel Berthe
2022-10-02 21:51:02 +02:00
parent 31f3bc3a85
commit edda23923b
4 changed files with 62 additions and 0 deletions

View File

@@ -2,6 +2,12 @@
@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade. @samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade.
## 1.29.0 (2022-10-02)
Adding:
- lo.ErrorAs
## 1.28.0 (2022-09-05) ## 1.28.0 (2022-09-05)
Adding: Adding:

View File

@@ -212,6 +212,7 @@ Error handling:
- [TryCatch](#trycatch) - [TryCatch](#trycatch)
- [TryWithErrorValue](#trywitherrorvalue) - [TryWithErrorValue](#trywitherrorvalue)
- [TryCatchWithErrorValue](#trycatchwitherrorvalue) - [TryCatchWithErrorValue](#trycatchwitherrorvalue)
- [ErrorsAs](#errorsas)
Constraints: Constraints:
@@ -2071,6 +2072,29 @@ ok := lo.TryCatchWithErrorValue(func() error {
// caught == true // caught == true
``` ```
### ErrorsAs
A shortcut for:
```go
err := doSomething()
var rateLimitErr *RateLimitError
if ok := errors.As(err, &rateLimitErr); ok {
// retry later
}
```
1 line `lo` helper:
```go
err := doSomething()
if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok {
// retry later
}
```
## 🛩 Benchmark ## 🛩 Benchmark
We executed a simple benchmark with the a dead-simple `lo.Map` loop: We executed a simple benchmark with the a dead-simple `lo.Map` loop:

View File

@@ -1,6 +1,7 @@
package lo package lo
import ( import (
"errors"
"fmt" "fmt"
"reflect" "reflect"
) )
@@ -199,3 +200,10 @@ func TryCatchWithErrorValue(callback func() error, catch func(any)) {
catch(err) catch(err)
} }
} }
// ErrorsAs is a shortcut for errors.As(err, &&T).
func ErrorsAs[T error](err error) (T, bool) {
var t T
ok := errors.As(err, &t)
return t, ok
}

View File

@@ -361,3 +361,27 @@ func TestTryCatchWithErrorValue(t *testing.T) {
}) })
is.False(caught) is.False(caught)
} }
type internalError struct {
foobar string
}
func (e *internalError) Error() string {
return fmt.Sprintf("internal error")
}
func TestErrorsAs(t *testing.T) {
is := assert.New(t)
err, ok := ErrorsAs[*internalError](fmt.Errorf("hello world"))
is.False(ok)
is.Nil(nil, err)
err, ok = ErrorsAs[*internalError](&internalError{foobar: "foobar"})
is.True(ok)
is.Equal(&internalError{foobar: "foobar"}, err)
err, ok = ErrorsAs[*internalError](nil)
is.False(ok)
is.Nil(nil, err)
}