/
errors.go
77 lines (67 loc) · 2.12 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package encryption
import (
"strings"
"time"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/wait"
)
// isConnectionRefusedError checks if the error string include "connection refused"
// TODO: find a "go-way" to detect this error, probably using *os.SyscallError
func isConnectionRefusedError(err error) bool {
return strings.Contains(err.Error(), "connection refused")
}
// transientAPIError returns true if the provided error indicates that a retry
// against an HA server has a good chance to succeed.
func transientAPIError(err error) bool {
switch {
case err == nil:
return false
case errors.IsServerTimeout(err), errors.IsTooManyRequests(err), net.IsProbableEOF(err), net.IsConnectionReset(err), net.IsNoRoutesError(err), isConnectionRefusedError(err):
return true
default:
return false
}
}
func orError(a, b func(error) bool) func(error) bool {
return func(err error) bool {
return a(err) || b(err)
}
}
func onErrorWithTimeout(timeout time.Duration, backoff wait.Backoff, errorFunc func(error) bool, fn func() error) error {
var lastMatchingError error
stopCh := time.After(timeout)
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
select {
case <-stopCh:
return false, wait.ErrWaitTimeout
default:
}
err := fn()
switch {
case err == nil:
return true, nil
case errorFunc(err):
lastMatchingError = err
return false, nil
default:
return false, err
}
})
if err == wait.ErrWaitTimeout && lastMatchingError != nil {
err = lastMatchingError
}
return err
}