...

Source file src/k8s.io/apimachinery/pkg/util/wait/error.go

Documentation: k8s.io/apimachinery/pkg/util/wait

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package wait
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  )
    23  
    24  // ErrWaitTimeout is returned when the condition was not satisfied in time.
    25  //
    26  // Deprecated: This type will be made private in favor of Interrupted()
    27  // for checking errors or ErrorInterrupted(err) for returning a wrapped error.
    28  var ErrWaitTimeout = ErrorInterrupted(errors.New("timed out waiting for the condition"))
    29  
    30  // Interrupted returns true if the error indicates a Poll, ExponentialBackoff, or
    31  // Until loop exited for any reason besides the condition returning true or an
    32  // error. A loop is considered interrupted if the calling context is cancelled,
    33  // the context reaches its deadline, or a backoff reaches its maximum allowed
    34  // steps.
    35  //
    36  // Callers should use this method instead of comparing the error value directly to
    37  // ErrWaitTimeout, as methods that cancel a context may not return that error.
    38  //
    39  // Instead of:
    40  //
    41  //	err := wait.Poll(...)
    42  //	if err == wait.ErrWaitTimeout {
    43  //	    log.Infof("Wait for operation exceeded")
    44  //	} else ...
    45  //
    46  // Use:
    47  //
    48  //	err := wait.Poll(...)
    49  //	if wait.Interrupted(err) {
    50  //	    log.Infof("Wait for operation exceeded")
    51  //	} else ...
    52  func Interrupted(err error) bool {
    53  	switch {
    54  	case errors.Is(err, errWaitTimeout),
    55  		errors.Is(err, context.Canceled),
    56  		errors.Is(err, context.DeadlineExceeded):
    57  		return true
    58  	default:
    59  		return false
    60  	}
    61  }
    62  
    63  // errInterrupted
    64  type errInterrupted struct {
    65  	cause error
    66  }
    67  
    68  // ErrorInterrupted returns an error that indicates the wait was ended
    69  // early for a given reason. If no cause is provided a generic error
    70  // will be used but callers are encouraged to provide a real cause for
    71  // clarity in debugging.
    72  func ErrorInterrupted(cause error) error {
    73  	switch cause.(type) {
    74  	case errInterrupted:
    75  		// no need to wrap twice since errInterrupted is only needed
    76  		// once in a chain
    77  		return cause
    78  	default:
    79  		return errInterrupted{cause}
    80  	}
    81  }
    82  
    83  // errWaitTimeout is the private version of the previous ErrWaitTimeout
    84  // and is private to prevent direct comparison. Use ErrorInterrupted(err)
    85  // to get an error that will return true for Interrupted(err).
    86  var errWaitTimeout = errInterrupted{}
    87  
    88  func (e errInterrupted) Unwrap() error        { return e.cause }
    89  func (e errInterrupted) Is(target error) bool { return target == errWaitTimeout }
    90  func (e errInterrupted) Error() string {
    91  	if e.cause == nil {
    92  		// returns the same error message as historical behavior
    93  		return "timed out waiting for the condition"
    94  	}
    95  	return e.cause.Error()
    96  }
    97  

View as plain text