Skip to content
Merged
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

`go get github.com/objenious/errorutil`

## Delayed errors

```go
func foo() error {
err := bar()
timer := time.Hour
if err != nil {
// it should be delayed 1h later
return errorutil.WithDelay(err, timer)
}
return bar() // will not be delayed
}

func main() {
err := foo()
time.AfterFunc(errorutil.Delay(err), func() {
...
})
}
```

## Retryable errors

```go
Expand Down
58 changes: 58 additions & 0 deletions delayed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package errorutil

import (
"github.com/pkg/errors"
"time"
)

// Delayer defines an error that
type Delayer interface {
Delay() time.Duration
}

// Delay return the delay duration of a DelayedError (i.e. implements Delayer).
// If the error is nil or does not implement Delayer or the delay is not a positive value, 0 is returned.
func Delay(err error) time.Duration {
type causer interface {
Cause() error
}

for err != nil {
if delay, ok := err.(Delayer); ok {
return delay.Delay()
}
cause, ok := err.(causer)
if !ok {
break
}
err = cause.Cause()
}
return 0
}

// DelayedError set error delay duration. returns nil if the error is nil.
func WithDelay(err error, duration time.Duration) error {
if err == nil {
return nil
}
return &delayedError{error: err, duration: duration}
}

// NewDelayedError returns a delayed error that formats as the given text and duration.
func NewDelayedError(text string, duration time.Duration) error {
return WithDelay(errors.New(text), duration)
}

type delayedError struct {
error
duration time.Duration
}


func (err *delayedError) Delay() time.Duration {
return err.duration
}

func (err *delayedError) Cause() error {
return err.error
}
39 changes: 39 additions & 0 deletions delayed_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package errorutil

import (
"github.com/pkg/errors"
"testing"
"time"
)

func TestDelay(t *testing.T) {

// err := errorutil.NewRetryableError("Delayed Error Test")
tests := []struct {
err error
want time.Duration
}{
{nil, 0},
{WithDelay(nil, 0), 0},
{WithDelay(nil, 10), 0},
{WithDelay(errors.New("foo"), 0), 0},
{WithDelay(errors.New("foo"), 10), 10},
}
err := WithDelay(errors.New("foobar"), 10)
if err.Error() != "foobar" {
t.Errorf("WithDelay(%q): got: %v, want %v", err, err.Error(), "foobar")
}
for _, tt := range tests {
got := Delay(tt.err)
if got != tt.want {
t.Errorf("WithDelay(%q): got: %v, want %v", tt.err, got, tt.want)
}
}
}

func TestNewDelayedError(t *testing.T) {
err := NewDelayedError("delayed Error", 10)
if err.Error() != "delayed Error" {
t.Errorf("NewDelayedError expected %s, got %s", "delayed Error", err.Error())
}
}