Skip to content

Commit 31ee857

Browse files
committed
fix: treat rate limiter deadline as a context deadline
There's no dedicated error type for rate limiter "would exceed context deadline" error, hence we check the error message https://cs.opensource.google/go/x/time/+/refs/tags/v0.10.0:rate/rate.go;l=276
1 parent 8c2dae2 commit 31ee857

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

pkg/kstatus/polling/statusreaders/common.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func errResourceToResourceStatus(err error, resource *unstructured.Unstructured,
167167
// If the error is from the context, we don't attach that to the ResourceStatus,
168168
// but just return it directly so the caller can decide how to handle this
169169
// situation.
170-
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
170+
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) || isRateLimiterContextDeadlineExceeded(err) {
171171
return nil, err
172172
}
173173
identifier := object.UnstructuredToObjMetadata(resource)
@@ -193,7 +193,7 @@ func errIdentifierToResourceStatus(err error, identifier object.ObjMetadata) (*e
193193
// If the error is from the context, we don't attach that to the ResourceStatus,
194194
// but just return it directly so the caller can decide how to handle this
195195
// situation.
196-
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
196+
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) || isRateLimiterContextDeadlineExceeded(err) {
197197
return nil, err
198198
}
199199
if apierrors.IsNotFound(err) {
@@ -209,3 +209,20 @@ func errIdentifierToResourceStatus(err error, identifier object.ObjMetadata) (*e
209209
Error: err,
210210
}, nil
211211
}
212+
213+
// isRateLimiterContextDeadlineExceeded checks if the error is a rate limiter "would exceed context deadline" error
214+
// this allows us to treat it the same way as the context.Canceled and context.DeadlineExceeded errors
215+
// instead of attaching the error to the ResourceStatus, caller can decide how to handle this
216+
func isRateLimiterContextDeadlineExceeded(err error) bool {
217+
for {
218+
next := errors.Unwrap(err)
219+
if next == nil {
220+
break
221+
}
222+
err = next
223+
}
224+
225+
// there's no dedicated error type for this, hence we check the error message
226+
// https://cs.opensource.google/go/x/time/+/refs/tags/v0.10.0:rate/rate.go;l=276
227+
return err != nil && err.Error() == "rate: Wait(n=1) would exceed context deadline"
228+
}

pkg/kstatus/polling/statusreaders/common_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ func TestLookupResource(t *testing.T) {
7676
expectErr: true,
7777
expectedErrMessage: context.Canceled.Error(),
7878
},
79+
"rate would exceed context deadline": {
80+
identifier: deploymentIdentifier,
81+
readerErr: fmt.Errorf("client rate limiter Wait returned an error: %w", fmt.Errorf("rate: Wait(n=1) would exceed context deadline")),
82+
expectErr: true,
83+
expectedErrMessage: "client rate limiter Wait returned an error: rate: Wait(n=1) would exceed context deadline",
84+
},
85+
"rate would exceed context deadline wrapped error": {
86+
identifier: deploymentIdentifier,
87+
readerErr: fmt.Errorf("wrapped deeper: %w",
88+
fmt.Errorf("client rate limiter Wait returned an error: %w", fmt.Errorf("rate: Wait(n=1) would exceed context deadline"))),
89+
expectErr: true,
90+
expectedErrMessage: "wrapped deeper: client rate limiter Wait returned an error: rate: Wait(n=1) would exceed context deadline",
91+
},
7992
}
8093

8194
for tn, tc := range testCases {

0 commit comments

Comments
 (0)