From 54c42e0cca6b9bbb768b09ce9eeaa55df9788805 Mon Sep 17 00:00:00 2001 From: Jamie Edge Date: Sat, 24 Dec 2022 10:25:05 +0000 Subject: [PATCH 1/2] fix: return last non-nil value when unwrapping errors Refs: #78 --- retry.go | 2 +- retry_test.go | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/retry.go b/retry.go index 1182fc0..3e6e3fc 100644 --- a/retry.go +++ b/retry.go @@ -243,7 +243,7 @@ when you need unwrap all erros, you should use `WrappedErrors()` instead added in version 4.2.0 */ func (e Error) Unwrap() error { - return e[len(e)-1] + return e[lenWithoutNil(e)-1] } func lenWithoutNil(e Error) (count int) { diff --git a/retry_test.go b/retry_test.go index 4312409..b7f35b7 100644 --- a/retry_test.go +++ b/retry_test.go @@ -163,16 +163,17 @@ func TestLastErrorOnly(t *testing.T) { func TestUnrecoverableError(t *testing.T) { attempts := 0 - expectedErr := errors.New("error") + testErr := errors.New("error") + expectedErr := Error{testErr, nil} err := Do( func() error { attempts++ - return Unrecoverable(expectedErr) + return Unrecoverable(testErr) }, Attempts(2), - LastErrorOnly(true), ) assert.Equal(t, expectedErr, err) + assert.Equal(t, testErr, errors.Unwrap(err)) assert.Equal(t, 1, attempts, "unrecoverable error broke the loop") } From 56486baaa6fc6a2c72556bcdcda873437d05fc8c Mon Sep 17 00:00:00 2001 From: Jamie Edge Date: Sat, 24 Dec 2022 10:58:25 +0000 Subject: [PATCH 2/2] fix: reslice error log to remove nil values Refs: #80 --- retry.go | 4 ++-- retry_test.go | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/retry.go b/retry.go index 3e6e3fc..8b440be 100644 --- a/retry.go +++ b/retry.go @@ -157,7 +157,7 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error { } n++ errorLog[n] = config.context.Err() - return errorLog + return errorLog[:lenWithoutNil(errorLog)] } } else { @@ -175,7 +175,7 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error { if config.lastErrorOnly { return errorLog[lastErrIndex] } - return errorLog + return errorLog[:lenWithoutNil(errorLog)] } func newDefaultRetryConfig() *Config { diff --git a/retry_test.go b/retry_test.go index b7f35b7..78d47e9 100644 --- a/retry_test.go +++ b/retry_test.go @@ -31,6 +31,7 @@ func TestDoAllFailed(t *testing.T) { #8: test #9: test #10: test` + assert.Len(t, err, 10) assert.Equal(t, expectedErrorFormat, err.Error(), "retry error format") assert.Equal(t, uint(45), retrySum, "right count of retry") } @@ -68,6 +69,7 @@ func TestRetryIf(t *testing.T) { #1: test #2: test #3: special` + assert.Len(t, err, 3) assert.Equal(t, expectedErrorFormat, err.Error(), "retry error format") assert.Equal(t, uint(2), retryCount, "right count of retry") @@ -164,7 +166,7 @@ func TestLastErrorOnly(t *testing.T) { func TestUnrecoverableError(t *testing.T) { attempts := 0 testErr := errors.New("error") - expectedErr := Error{testErr, nil} + expectedErr := Error{testErr} err := Do( func() error { attempts++ @@ -367,6 +369,7 @@ func TestContext(t *testing.T) { #1: test #2: test #3: context canceled` + assert.Len(t, err, 3) assert.Equal(t, expectedErrorFormat, err.Error(), "retry error format") assert.Equal(t, 2, retrySum, "called at most once") })