Skip to content

Commit 9435796

Browse files
authored
Fix nil error got returned when there was error after retry (#5224)
Signed-off-by: Alex Le <leqiyue@amazon.com>
1 parent ddfc2e7 commit 9435796

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

pkg/storage/bucket/s3/bucket_client.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package s3
22

33
import (
44
"context"
5+
"fmt"
56
"io"
67
"time"
78

@@ -102,7 +103,7 @@ type BucketWithRetries struct {
102103
retryMaxBackoff time.Duration
103104
}
104105

105-
func (b *BucketWithRetries) retry(ctx context.Context, f func() error) error {
106+
func (b *BucketWithRetries) retry(ctx context.Context, f func() error, operationInfo string) error {
106107
var lastErr error
107108
retries := backoff.New(ctx, backoff.Config{
108109
MinBackoff: b.retryMinBackoff,
@@ -120,7 +121,8 @@ func (b *BucketWithRetries) retry(ctx context.Context, f func() error) error {
120121
retries.Wait()
121122
}
122123
if lastErr != nil {
123-
level.Error(b.logger).Log("msg", "bucket operation fail after retries", "err", lastErr)
124+
level.Error(b.logger).Log("msg", "bucket operation fail after retries", "err", lastErr, "operation", operationInfo)
125+
return lastErr
124126
}
125127
return nil
126128
}
@@ -132,30 +134,30 @@ func (b *BucketWithRetries) Name() string {
132134
func (b *BucketWithRetries) Iter(ctx context.Context, dir string, f func(string) error, options ...objstore.IterOption) error {
133135
return b.retry(ctx, func() error {
134136
return b.bucket.Iter(ctx, dir, f, options...)
135-
})
137+
}, fmt.Sprintf("Iter %s", dir))
136138
}
137139

138140
func (b *BucketWithRetries) Get(ctx context.Context, name string) (reader io.ReadCloser, err error) {
139141
err = b.retry(ctx, func() error {
140142
reader, err = b.bucket.Get(ctx, name)
141143
return err
142-
})
144+
}, fmt.Sprintf("Get %s", name))
143145
return
144146
}
145147

146148
func (b *BucketWithRetries) GetRange(ctx context.Context, name string, off, length int64) (closer io.ReadCloser, err error) {
147149
err = b.retry(ctx, func() error {
148150
closer, err = b.bucket.GetRange(ctx, name, off, length)
149151
return err
150-
})
152+
}, fmt.Sprintf("GetRange %s (off: %d, length: %d)", name, off, length))
151153
return
152154
}
153155

154156
func (b *BucketWithRetries) Exists(ctx context.Context, name string) (exists bool, err error) {
155157
err = b.retry(ctx, func() error {
156158
exists, err = b.bucket.Exists(ctx, name)
157159
return err
158-
})
160+
}, fmt.Sprintf("Exists %s", name))
159161
return
160162
}
161163

@@ -171,21 +173,21 @@ func (b *BucketWithRetries) Upload(ctx context.Context, name string, r io.Reader
171173
return err
172174
}
173175
return b.bucket.Upload(ctx, name, rs)
174-
})
176+
}, fmt.Sprintf("Upload %s", name))
175177
}
176178

177179
func (b *BucketWithRetries) Attributes(ctx context.Context, name string) (attributes objstore.ObjectAttributes, err error) {
178180
err = b.retry(ctx, func() error {
179181
attributes, err = b.bucket.Attributes(ctx, name)
180182
return err
181-
})
183+
}, fmt.Sprintf("Attributes %s", name))
182184
return
183185
}
184186

185187
func (b *BucketWithRetries) Delete(ctx context.Context, name string) error {
186188
return b.retry(ctx, func() error {
187189
return b.bucket.Delete(ctx, name)
188-
})
190+
}, fmt.Sprintf("Delete %s", name))
189191
}
190192

191193
func (b *BucketWithRetries) IsObjNotFoundErr(err error) bool {

pkg/storage/bucket/s3/bucket_client_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/go-kit/log"
1112
"github.com/stretchr/testify/require"
1213
"github.com/thanos-io/objstore"
1314
)
@@ -19,6 +20,7 @@ func TestBucketWithRetries_UploadSeekable(t *testing.T) {
1920
FailCount: 3,
2021
}
2122
b := BucketWithRetries{
23+
logger: log.NewNopLogger(),
2224
bucket: &m,
2325
operationRetries: 5,
2426
retryMinBackoff: 10 * time.Millisecond,
@@ -39,6 +41,7 @@ func TestBucketWithRetries_UploadNonSeekable(t *testing.T) {
3941
FailCount: maxFailCount,
4042
}
4143
b := BucketWithRetries{
44+
logger: log.NewNopLogger(),
4245
bucket: &m,
4346
operationRetries: 5,
4447
retryMinBackoff: 10 * time.Millisecond,
@@ -51,6 +54,25 @@ func TestBucketWithRetries_UploadNonSeekable(t *testing.T) {
5154
require.Equal(t, maxFailCount, m.FailCount)
5255
}
5356

57+
func TestBucketWithRetries_UploadFailed(t *testing.T) {
58+
t.Parallel()
59+
60+
m := mockBucket{
61+
FailCount: 6,
62+
}
63+
b := BucketWithRetries{
64+
logger: log.NewNopLogger(),
65+
bucket: &m,
66+
operationRetries: 5,
67+
retryMinBackoff: 10 * time.Millisecond,
68+
retryMaxBackoff: time.Second,
69+
}
70+
71+
input := []byte("test input")
72+
err := b.Upload(context.Background(), "dummy", bytes.NewReader(input))
73+
require.ErrorContains(t, err, "failed upload: ")
74+
}
75+
5476
type fakeReader struct {
5577
}
5678

0 commit comments

Comments
 (0)