diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go index 89a3ceaaac7..57e0e71f672 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go @@ -96,8 +96,8 @@ func HasStatusCause(err error, name metav1.CauseType) bool { // StatusCause returns the named cause from the provided error if it exists and // the error unwraps to the type APIStatus. Otherwise it returns false. func StatusCause(err error, name metav1.CauseType) (metav1.StatusCause, bool) { - var status APIStatus - if errors.As(err, &status) && status.Status().Details != nil { + status, ok := err.(APIStatus) + if (ok || errors.As(err, &status)) && status.Status().Details != nil { for _, cause := range status.Status().Details.Causes { if cause.Type == name { return cause, true @@ -757,7 +757,8 @@ func IsRequestEntityTooLargeError(err error) bool { // and may be the result of another HTTP actor. // It supports wrapped errors and returns false when the error is nil. func IsUnexpectedServerError(err error) bool { - if status := APIStatus(nil); errors.As(err, &status) && status.Status().Details != nil { + status, ok := err.(APIStatus) + if (ok || errors.As(err, &status)) && status.Status().Details != nil { for _, cause := range status.Status().Details.Causes { if cause.Type == metav1.CauseTypeUnexpectedServerResponse { return true @@ -770,8 +771,8 @@ func IsUnexpectedServerError(err error) bool { // IsUnexpectedObjectError determines if err is due to an unexpected object from the master. // It supports wrapped errors and returns false when the error is nil. func IsUnexpectedObjectError(err error) bool { - uoe := &UnexpectedObjectError{} - return err != nil && errors.As(err, &uoe) + uoe, ok := err.(*UnexpectedObjectError) + return err != nil && (ok || errors.As(err, &uoe)) } // SuggestsClientDelay returns true if this error suggests a client delay as well as the @@ -780,7 +781,8 @@ func IsUnexpectedObjectError(err error) bool { // request delay without retry. // It supports wrapped errors and returns false when the error is nil. func SuggestsClientDelay(err error) (int, bool) { - if t := APIStatus(nil); errors.As(err, &t) && t.Status().Details != nil { + t, ok := err.(APIStatus) + if (ok || errors.As(err, &t)) && t.Status().Details != nil { switch t.Status().Reason { // this StatusReason explicitly requests the caller to delay the action case metav1.StatusReasonServerTimeout: @@ -798,14 +800,14 @@ func SuggestsClientDelay(err error) (int, bool) { // It supports wrapped errors and returns StatusReasonUnknown when // the error is nil or doesn't have a status. func ReasonForError(err error) metav1.StatusReason { - if status := APIStatus(nil); errors.As(err, &status) { + if status, ok := err.(APIStatus); ok || errors.As(err, &status) { return status.Status().Reason } return metav1.StatusReasonUnknown } func reasonAndCodeForError(err error) (metav1.StatusReason, int32) { - if status := APIStatus(nil); errors.As(err, &status) { + if status, ok := err.(APIStatus); ok || errors.As(err, &status) { return status.Status().Reason, status.Status().Code } return metav1.StatusReasonUnknown, 0 diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go index 5feb287d846..b67bf885b3e 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go @@ -657,3 +657,49 @@ func TestStatusCauseSupportsWrappedErrors(t *testing.T) { t.Errorf("expected cause when nested, got %v: %#v", ok, cause) } } + +func BenchmarkIsAlreadyExistsWrappedErrors(b *testing.B) { + err := NewAlreadyExists(schema.GroupResource{}, "") + wrapped := fmt.Errorf("once: %w", err) + + b.Run("Nil", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsAlreadyExists(nil) + } + }) + + b.Run("Bare", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsAlreadyExists(err) + } + }) + + b.Run("Wrapped", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsAlreadyExists(wrapped) + } + }) +} + +func BenchmarkIsNotFoundWrappedErrors(b *testing.B) { + err := NewNotFound(schema.GroupResource{}, "") + wrapped := fmt.Errorf("once: %w", err) + + b.Run("Nil", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsNotFound(nil) + } + }) + + b.Run("Bare", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsNotFound(err) + } + }) + + b.Run("Wrapped", func(b *testing.B) { + for i := 0; i < b.N; i++ { + IsNotFound(wrapped) + } + }) +}