Skip to content

Commit

Permalink
add delayed errors (#7)
Browse files Browse the repository at this point in the history
* Adding DelayedError

* minor fix

* langage optimization
  • Loading branch information
gregoryduquesnoy authored and jfbus committed Feb 5, 2019
1 parent 3f26d94 commit f5f6739
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
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())
}
}

0 comments on commit f5f6739

Please sign in to comment.