From 8ed86518c94a32ed136ec5d4db37333686f5b818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B8=D0=BD=D0=BA=D0=B5=D0=B2=D0=B8=D1=87=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9C=D0=B8=D1=85=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2=D0=B8=D1=87?= Date: Fri, 16 Jun 2023 17:44:50 +0700 Subject: [PATCH] wrapped error handling --- repeater.go | 8 ++++---- repeater_test.go | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/repeater.go b/repeater.go index 612d754..4203427 100644 --- a/repeater.go +++ b/repeater.go @@ -5,6 +5,7 @@ package repeater import ( "context" + "errors" "time" "github.com/go-pkgz/repeater/strategy" @@ -35,14 +36,13 @@ func NewDefault(repeats int, delay time.Duration) *Repeater { } // Do repeats fun till no error. Predefined (optional) errors terminate immediately -func (r Repeater) Do(ctx context.Context, fun func() error, errors ...error) (err error) { - +func (r Repeater) Do(ctx context.Context, fun func() error, errs ...error) (err error) { ctx, cancelFunc := context.WithCancel(ctx) defer cancelFunc() // ensure strategy's channel termination inErrors := func(err error) bool { - for _, e := range errors { - if e == err { + for _, e := range errs { + if errors.Is(err, e) { return true } } diff --git a/repeater_test.go b/repeater_test.go index 200c030..b20329b 100644 --- a/repeater_test.go +++ b/repeater_test.go @@ -101,7 +101,24 @@ func TestRepeaterFixedCriticalError(t *testing.T) { } err := NewDefault(10, time.Millisecond).Do(context.Background(), fun, criticalErr) - assert.Equal(t, criticalErr, err) + assert.ErrorIs(t, err, criticalErr) + assert.Equal(t, 5, called, "called 5 times") +} + +func TestRepeaterFixedCriticalErrorWrap(t *testing.T) { + criticalErr := errors.New("critical error") + + called := 0 + fun := func() error { + called++ + if called == 5 { + return fmt.Errorf("wrap err: %w", criticalErr) + } + return errors.New("some error") + } + + err := NewDefault(10, time.Millisecond).Do(context.Background(), fun, criticalErr) + assert.ErrorIs(t, err, criticalErr) assert.Equal(t, 5, called, "called 5 times") } @@ -160,7 +177,7 @@ func TestRepeaterBackoffFailed(t *testing.T) { } called = 0 err = New(&strtg).Do(context.Background(), fun) - assert.Equal(t, e, err) + assert.ErrorIs(t, err, e) assert.Equal(t, 1, called, "called 1 times") } @@ -183,10 +200,11 @@ func TestRepeaterBackoffCanceled(t *testing.T) { } err := New(&strtg).Do(ctx, fun) - require.NotNil(t, err) + require.Error(t, err) assert.True(t, err.Error() == "context deadline exceeded" || err.Error() == "some error") assert.Equal(t, 6, called) } + func TestRepeaterOnce(t *testing.T) { e := errors.New("some error") called := 0 @@ -196,13 +214,13 @@ func TestRepeaterOnce(t *testing.T) { } err := New(&strategy.Once{}).Do(context.Background(), fun) - assert.Equal(t, e, err) + assert.ErrorIs(t, err, e) assert.Equal(t, 1, called, "called 1 time") called = 0 e = nil err = New(&strategy.Once{}).Do(context.Background(), fun) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, 1, called, "called 1 time") } @@ -225,7 +243,6 @@ func TestRepeaterNil(t *testing.T) { } func TestRepeaterMemoryLeakFixed(t *testing.T) { - rep := func() { called := 0 fun := func() error { @@ -254,7 +271,6 @@ func TestRepeaterMemoryLeakFixed(t *testing.T) { } func TestRepeaterMemoryLeakBackOff(t *testing.T) { - rep := func() { called := 0 fun := func() error {