# try [![GoDoc](https://godoc.org/github.com/matryer/try?status.svg)](https://godoc.org/github.com/matryer/try) [![Go Report Card](https://goreportcard.com/badge/github.com/matryer/try)](https://goreportcard.com/report/github.com/matryer/try)
Idiomatic Go retry package. Thanks to [@rowland](https://github.com/rowland) for code review.
```
go get gopkg.in/matryer/try.v1
or
drop gopkg.in/matryer/try.v1
```
* Learn more about [Drop](https://github.com/matryer/drop)
### Usage
Just call `try.Do` with the function you want to retry in the event of an error:
* Call `try.Do` that returns a `bool` indicating whether to retry or not, and an `error`
* The `attempt` argument will start at 1 and count up
* `try.Do` blocks until you return `false`, or a `nil` error
* `try.Do` returns the last error or `nil` if it was successful
```
var value string
err := try.Do(func(attempt int) (bool, error) {
var err error
value, err = SomeFunction()
return attempt < 5, err // try 5 times
})
if err != nil {
log.Fatalln("error:", err)
}
```
In the above example the function will be called repeatedly until error is `nil`, while `attempt < 5` (i.e. try 5 times)
#### Retrying panics
Try supports retrying in the event of a panic.
* Use named return parameters
* Set `retry` first
* Defer the recovery code, and set `err` manually in the case of a panic
* Use empty `return` statement at the end
```
var value string
err := try.Do(func(attempt int) (retry bool, err error) {
retry = attempt < 5 // try 5 times
defer func() {
if r := recover(); r != nil {
err = errors.New(fmt.Sprintf("panic: %v", r))
}
}()
value, err = SomeFunction()
return
})
if err != nil {
log.Fatalln("error:", err)
}
```
#### Delay between retries
To introduce a delay between retries, just make a `time.Sleep` call before you return from the function if you are returning an error.
```
var value string
err := try.Do(func(attempt int) (bool, error) {
var err error
value, err = SomeFunction()
if err != nil {
time.Sleep(1 * time.Minute) // wait a minute
}
return attempt < 5, err
})
if err != nil {
log.Fatalln("error:", err)
}
```
#### Maximum retry limit
To avoid infinite loops, Try will ensure it only makes `try.MaxRetries` attempts. By default, this value is `10`, but you can change it:
```
try.MaxRetries = 20
```
To see if a `Do` operation failed due to reaching the limit, you can check the `error` with `try.IsMaxRetries(err)`.