Skip to content

Commit 5de4674

Browse files
authored
fix DNS timeout error not retried (#2300)
1 parent e155bb7 commit 5de4674

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"id": "63caeb72-930c-4d84-bbab-8d36fe10d4b5",
3+
"type": "bugfix",
4+
"description": "Improve recognition of retryable DNS errors.",
5+
"modules": [
6+
"."
7+
]
8+
}

aws/retry/retryable_error.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,21 @@ func (r RetryableConnectionError) IsErrorRetryable(err error) aws.Ternary {
9797
var netOpErr *net.OpError
9898
var dnsError *net.DNSError
9999

100-
switch {
101-
case errors.As(err, &dnsError):
100+
if errors.As(err, &dnsError) {
102101
// NXDOMAIN errors should not be retried
103-
retryable = !dnsError.IsNotFound && dnsError.IsTemporary
102+
if dnsError.IsNotFound {
103+
return aws.BoolTernary(false)
104+
}
105+
106+
// if !dnsError.Temporary(), error may or may not be temporary,
107+
// (i.e. !Temporary() =/=> !retryable) so we should fall through to
108+
// remaining checks
109+
if dnsError.Temporary() {
110+
return aws.BoolTernary(true)
111+
}
112+
}
104113

114+
switch {
105115
case errors.As(err, &conErr) && conErr.ConnectionError():
106116
retryable = true
107117

aws/retry/retryable_error_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,47 @@ func TestCanceledError(t *testing.T) {
262262
})
263263
}
264264
}
265+
266+
func TestDNSError(t *testing.T) {
267+
cases := map[string]struct {
268+
Err error
269+
Expect aws.Ternary
270+
}{
271+
"IsNotFound": {
272+
Err: &net.DNSError{
273+
IsNotFound: true,
274+
},
275+
Expect: aws.FalseTernary,
276+
},
277+
"Temporary (IsTimeout)": {
278+
Err: &net.DNSError{
279+
IsTimeout: true,
280+
},
281+
Expect: aws.TrueTernary,
282+
},
283+
"Temporary (IsTemporary)": {
284+
Err: &net.DNSError{
285+
IsTemporary: true,
286+
},
287+
Expect: aws.TrueTernary,
288+
},
289+
"Temporary() == false but it falls through": {
290+
Err: &net.OpError{
291+
Op: "dial",
292+
Err: &net.DNSError{},
293+
},
294+
Expect: aws.TrueTernary,
295+
},
296+
}
297+
298+
for name, c := range cases {
299+
t.Run(name, func(t *testing.T) {
300+
var r RetryableConnectionError
301+
302+
retryable := r.IsErrorRetryable(c.Err)
303+
if e, a := c.Expect, retryable; e != a {
304+
t.Errorf("expect %v retryable, got %v", e, a)
305+
}
306+
})
307+
}
308+
}

0 commit comments

Comments
 (0)