github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/nomad/structs/errors.go (about)

     1  package structs
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  const (
    11  	errNoLeader                   = "No cluster leader"
    12  	errNotReadyForConsistentReads = "Not ready to serve consistent reads"
    13  	errNoRegionPath               = "No path to region"
    14  	errTokenNotFound              = "ACL token not found"
    15  	errPermissionDenied           = "Permission denied"
    16  	errNoNodeConn                 = "No path to node"
    17  	errUnknownMethod              = "Unknown rpc method"
    18  	errUnknownNomadVersion        = "Unable to determine Nomad version"
    19  	errNodeLacksRpc               = "Node does not support RPC; requires 0.8 or later"
    20  	errMissingAllocID             = "Missing allocation ID"
    21  
    22  	// Prefix based errors that are used to check if the error is of a given
    23  	// type. These errors should be created with the associated constructor.
    24  	ErrUnknownAllocationPrefix = "Unknown allocation"
    25  	ErrUnknownNodePrefix       = "Unknown node"
    26  	ErrUnknownJobPrefix        = "Unknown job"
    27  	ErrUnknownEvaluationPrefix = "Unknown evaluation"
    28  	ErrUnknownDeploymentPrefix = "Unknown deployment"
    29  
    30  	errRPCCodedErrorPrefix = "RPC Error:: "
    31  
    32  	errDeploymentTerminalNoCancel    = "can't cancel terminal deployment"
    33  	errDeploymentTerminalNoFail      = "can't fail terminal deployment"
    34  	errDeploymentTerminalNoPause     = "can't pause terminal deployment"
    35  	errDeploymentTerminalNoPromote   = "can't promote terminal deployment"
    36  	errDeploymentTerminalNoResume    = "can't resume terminal deployment"
    37  	errDeploymentTerminalNoUnblock   = "can't unblock terminal deployment"
    38  	errDeploymentTerminalNoRun       = "can't run terminal deployment"
    39  	errDeploymentTerminalNoSetHealth = "can't set health of allocations for a terminal deployment"
    40  	errDeploymentRunningNoUnblock    = "can't unblock running deployment"
    41  )
    42  
    43  var (
    44  	ErrNoLeader                   = errors.New(errNoLeader)
    45  	ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads)
    46  	ErrNoRegionPath               = errors.New(errNoRegionPath)
    47  	ErrTokenNotFound              = errors.New(errTokenNotFound)
    48  	ErrPermissionDenied           = errors.New(errPermissionDenied)
    49  	ErrNoNodeConn                 = errors.New(errNoNodeConn)
    50  	ErrUnknownMethod              = errors.New(errUnknownMethod)
    51  	ErrUnknownNomadVersion        = errors.New(errUnknownNomadVersion)
    52  	ErrNodeLacksRpc               = errors.New(errNodeLacksRpc)
    53  	ErrMissingAllocID             = errors.New(errMissingAllocID)
    54  
    55  	ErrUnknownNode = errors.New(ErrUnknownNodePrefix)
    56  
    57  	ErrDeploymentTerminalNoCancel    = errors.New(errDeploymentTerminalNoCancel)
    58  	ErrDeploymentTerminalNoFail      = errors.New(errDeploymentTerminalNoFail)
    59  	ErrDeploymentTerminalNoPause     = errors.New(errDeploymentTerminalNoPause)
    60  	ErrDeploymentTerminalNoPromote   = errors.New(errDeploymentTerminalNoPromote)
    61  	ErrDeploymentTerminalNoResume    = errors.New(errDeploymentTerminalNoResume)
    62  	ErrDeploymentTerminalNoUnblock   = errors.New(errDeploymentTerminalNoUnblock)
    63  	ErrDeploymentTerminalNoRun       = errors.New(errDeploymentTerminalNoRun)
    64  	ErrDeploymentTerminalNoSetHealth = errors.New(errDeploymentTerminalNoSetHealth)
    65  	ErrDeploymentRunningNoUnblock    = errors.New(errDeploymentRunningNoUnblock)
    66  
    67  	ErrCSIClientRPCIgnorable = errors.New("CSI client error (ignorable)")
    68  	ErrCSIClientRPCRetryable = errors.New("CSI client error (retryable)")
    69  )
    70  
    71  // IsErrNoLeader returns whether the error is due to there being no leader.
    72  func IsErrNoLeader(err error) bool {
    73  	return err != nil && strings.Contains(err.Error(), errNoLeader)
    74  }
    75  
    76  // IsErrNoRegionPath returns whether the error is due to there being no path to
    77  // the given region.
    78  func IsErrNoRegionPath(err error) bool {
    79  	return err != nil && strings.Contains(err.Error(), errNoRegionPath)
    80  }
    81  
    82  // IsErrTokenNotFound returns whether the error is due to the passed token not
    83  // being resolvable.
    84  func IsErrTokenNotFound(err error) bool {
    85  	return err != nil && strings.Contains(err.Error(), errTokenNotFound)
    86  }
    87  
    88  // IsErrPermissionDenied returns whether the error is due to the operation not
    89  // being allowed due to lack of permissions.
    90  func IsErrPermissionDenied(err error) bool {
    91  	return err != nil && strings.Contains(err.Error(), errPermissionDenied)
    92  }
    93  
    94  // IsErrNoNodeConn returns whether the error is due to there being no path to
    95  // the given node.
    96  func IsErrNoNodeConn(err error) bool {
    97  	return err != nil && strings.Contains(err.Error(), errNoNodeConn)
    98  }
    99  
   100  // IsErrUnknownMethod returns whether the error is due to the operation not
   101  // being allowed due to lack of permissions.
   102  func IsErrUnknownMethod(err error) bool {
   103  	return err != nil && strings.Contains(err.Error(), errUnknownMethod)
   104  }
   105  
   106  func IsErrRPCCoded(err error) bool {
   107  	return err != nil && strings.HasPrefix(err.Error(), errRPCCodedErrorPrefix)
   108  }
   109  
   110  // NewErrUnknownAllocation returns a new error caused by the allocation being
   111  // unknown.
   112  func NewErrUnknownAllocation(allocID string) error {
   113  	return fmt.Errorf("%s %q", ErrUnknownAllocationPrefix, allocID)
   114  }
   115  
   116  // NewErrUnknownNode returns a new error caused by the node being unknown.
   117  func NewErrUnknownNode(nodeID string) error {
   118  	return fmt.Errorf("%s %q", ErrUnknownNodePrefix, nodeID)
   119  }
   120  
   121  // NewErrUnknownJob returns a new error caused by the job being unknown.
   122  func NewErrUnknownJob(jobID string) error {
   123  	return fmt.Errorf("%s %q", ErrUnknownJobPrefix, jobID)
   124  }
   125  
   126  // NewErrUnknownEvaluation returns a new error caused by the evaluation being
   127  // unknown.
   128  func NewErrUnknownEvaluation(evaluationID string) error {
   129  	return fmt.Errorf("%s %q", ErrUnknownEvaluationPrefix, evaluationID)
   130  }
   131  
   132  // NewErrUnknownDeployment returns a new error caused by the deployment being
   133  // unknown.
   134  func NewErrUnknownDeployment(deploymentID string) error {
   135  	return fmt.Errorf("%s %q", ErrUnknownDeploymentPrefix, deploymentID)
   136  }
   137  
   138  // IsErrUnknownAllocation returns whether the error is due to an unknown
   139  // allocation.
   140  func IsErrUnknownAllocation(err error) bool {
   141  	return err != nil && strings.Contains(err.Error(), ErrUnknownAllocationPrefix)
   142  }
   143  
   144  // IsErrUnknownNode returns whether the error is due to an unknown
   145  // node.
   146  func IsErrUnknownNode(err error) bool {
   147  	return err != nil && strings.Contains(err.Error(), ErrUnknownNodePrefix)
   148  }
   149  
   150  // IsErrUnknownJob returns whether the error is due to an unknown
   151  // job.
   152  func IsErrUnknownJob(err error) bool {
   153  	return err != nil && strings.Contains(err.Error(), ErrUnknownJobPrefix)
   154  }
   155  
   156  // IsErrUnknownEvaluation returns whether the error is due to an unknown
   157  // evaluation.
   158  func IsErrUnknownEvaluation(err error) bool {
   159  	return err != nil && strings.Contains(err.Error(), ErrUnknownEvaluationPrefix)
   160  }
   161  
   162  // IsErrUnknownDeployment returns whether the error is due to an unknown
   163  // deployment.
   164  func IsErrUnknownDeployment(err error) bool {
   165  	return err != nil && strings.Contains(err.Error(), ErrUnknownDeploymentPrefix)
   166  }
   167  
   168  // IsErrUnknownNomadVersion returns whether the error is due to Nomad being
   169  // unable to determine the version of a node.
   170  func IsErrUnknownNomadVersion(err error) bool {
   171  	return err != nil && strings.Contains(err.Error(), errUnknownNomadVersion)
   172  }
   173  
   174  // IsErrNodeLacksRpc returns whether error is due to a Nomad server being
   175  // unable to connect to a client node because the client is too old (pre-v0.8).
   176  func IsErrNodeLacksRpc(err error) bool {
   177  	return err != nil && strings.Contains(err.Error(), errNodeLacksRpc)
   178  }
   179  
   180  // NewErrRPCCoded wraps an RPC error with a code to be converted to HTTP status
   181  // code
   182  func NewErrRPCCoded(code int, msg string) error {
   183  	return fmt.Errorf("%s%d,%s", errRPCCodedErrorPrefix, code, msg)
   184  }
   185  
   186  // NewErrRPCCoded wraps an RPC error with a code to be converted to HTTP status
   187  // code
   188  func NewErrRPCCodedf(code int, format string, args ...interface{}) error {
   189  	msg := fmt.Sprintf(format, args...)
   190  	return fmt.Errorf("%s%d,%s", errRPCCodedErrorPrefix, code, msg)
   191  }
   192  
   193  // CodeFromRPCCodedErr returns the code and message of error if it's an RPC error
   194  // created through NewErrRPCCoded function.  Returns `ok` false if error is not
   195  // an rpc error
   196  func CodeFromRPCCodedErr(err error) (code int, msg string, ok bool) {
   197  	if err == nil || !strings.HasPrefix(err.Error(), errRPCCodedErrorPrefix) {
   198  		return 0, "", false
   199  	}
   200  
   201  	headerLen := len(errRPCCodedErrorPrefix)
   202  	parts := strings.SplitN(err.Error()[headerLen:], ",", 2)
   203  	if len(parts) != 2 {
   204  		return 0, "", false
   205  	}
   206  
   207  	code, err = strconv.Atoi(parts[0])
   208  	if err != nil {
   209  		return 0, "", false
   210  	}
   211  
   212  	return code, parts[1], true
   213  }