github.com/uchennaokeke444/nomad@v0.11.8/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 33 var ( 34 ErrNoLeader = errors.New(errNoLeader) 35 ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) 36 ErrNoRegionPath = errors.New(errNoRegionPath) 37 ErrTokenNotFound = errors.New(errTokenNotFound) 38 ErrPermissionDenied = errors.New(errPermissionDenied) 39 ErrNoNodeConn = errors.New(errNoNodeConn) 40 ErrUnknownMethod = errors.New(errUnknownMethod) 41 ErrUnknownNomadVersion = errors.New(errUnknownNomadVersion) 42 ErrNodeLacksRpc = errors.New(errNodeLacksRpc) 43 ErrMissingAllocID = errors.New(errMissingAllocID) 44 ) 45 46 // IsErrNoLeader returns whether the error is due to there being no leader. 47 func IsErrNoLeader(err error) bool { 48 return err != nil && strings.Contains(err.Error(), errNoLeader) 49 } 50 51 // IsErrNoRegionPath returns whether the error is due to there being no path to 52 // the given region. 53 func IsErrNoRegionPath(err error) bool { 54 return err != nil && strings.Contains(err.Error(), errNoRegionPath) 55 } 56 57 // IsErrTokenNotFound returns whether the error is due to the passed token not 58 // being resolvable. 59 func IsErrTokenNotFound(err error) bool { 60 return err != nil && strings.Contains(err.Error(), errTokenNotFound) 61 } 62 63 // IsErrPermissionDenied returns whether the error is due to the operation not 64 // being allowed due to lack of permissions. 65 func IsErrPermissionDenied(err error) bool { 66 return err != nil && strings.Contains(err.Error(), errPermissionDenied) 67 } 68 69 // IsErrNoNodeConn returns whether the error is due to there being no path to 70 // the given node. 71 func IsErrNoNodeConn(err error) bool { 72 return err != nil && strings.Contains(err.Error(), errNoNodeConn) 73 } 74 75 // IsErrUnknownMethod returns whether the error is due to the operation not 76 // being allowed due to lack of permissions. 77 func IsErrUnknownMethod(err error) bool { 78 return err != nil && strings.Contains(err.Error(), errUnknownMethod) 79 } 80 81 func IsErrRPCCoded(err error) bool { 82 return err != nil && strings.HasPrefix(err.Error(), errRPCCodedErrorPrefix) 83 } 84 85 // NewErrUnknownAllocation returns a new error caused by the allocation being 86 // unknown. 87 func NewErrUnknownAllocation(allocID string) error { 88 return fmt.Errorf("%s %q", ErrUnknownAllocationPrefix, allocID) 89 } 90 91 // NewErrUnknownNode returns a new error caused by the node being unknown. 92 func NewErrUnknownNode(nodeID string) error { 93 return fmt.Errorf("%s %q", ErrUnknownNodePrefix, nodeID) 94 } 95 96 // NewErrUnknownJob returns a new error caused by the job being unknown. 97 func NewErrUnknownJob(jobID string) error { 98 return fmt.Errorf("%s %q", ErrUnknownJobPrefix, jobID) 99 } 100 101 // NewErrUnknownEvaluation returns a new error caused by the evaluation being 102 // unknown. 103 func NewErrUnknownEvaluation(evaluationID string) error { 104 return fmt.Errorf("%s %q", ErrUnknownEvaluationPrefix, evaluationID) 105 } 106 107 // NewErrUnknownDeployment returns a new error caused by the deployment being 108 // unknown. 109 func NewErrUnknownDeployment(deploymentID string) error { 110 return fmt.Errorf("%s %q", ErrUnknownDeploymentPrefix, deploymentID) 111 } 112 113 // IsErrUnknownAllocation returns whether the error is due to an unknown 114 // allocation. 115 func IsErrUnknownAllocation(err error) bool { 116 return err != nil && strings.Contains(err.Error(), ErrUnknownAllocationPrefix) 117 } 118 119 // IsErrUnknownNode returns whether the error is due to an unknown 120 // node. 121 func IsErrUnknownNode(err error) bool { 122 return err != nil && strings.Contains(err.Error(), ErrUnknownNodePrefix) 123 } 124 125 // IsErrUnknownJob returns whether the error is due to an unknown 126 // job. 127 func IsErrUnknownJob(err error) bool { 128 return err != nil && strings.Contains(err.Error(), ErrUnknownJobPrefix) 129 } 130 131 // IsErrUnknownEvaluation returns whether the error is due to an unknown 132 // evaluation. 133 func IsErrUnknownEvaluation(err error) bool { 134 return err != nil && strings.Contains(err.Error(), ErrUnknownEvaluationPrefix) 135 } 136 137 // IsErrUnknownDeployment returns whether the error is due to an unknown 138 // deployment. 139 func IsErrUnknownDeployment(err error) bool { 140 return err != nil && strings.Contains(err.Error(), ErrUnknownDeploymentPrefix) 141 } 142 143 // IsErrUnknownNomadVersion returns whether the error is due to Nomad being 144 // unable to determine the version of a node. 145 func IsErrUnknownNomadVersion(err error) bool { 146 return err != nil && strings.Contains(err.Error(), errUnknownNomadVersion) 147 } 148 149 // IsErrNodeLacksRpc returns whether error is due to a Nomad server being 150 // unable to connect to a client node because the client is too old (pre-v0.8). 151 func IsErrNodeLacksRpc(err error) bool { 152 return err != nil && strings.Contains(err.Error(), errNodeLacksRpc) 153 } 154 155 // NewErrRPCCoded wraps an RPC error with a code to be converted to HTTP status 156 // code 157 func NewErrRPCCoded(code int, msg string) error { 158 return fmt.Errorf("%s%d,%s", errRPCCodedErrorPrefix, code, msg) 159 } 160 161 // NewErrRPCCoded wraps an RPC error with a code to be converted to HTTP status 162 // code 163 func NewErrRPCCodedf(code int, format string, args ...interface{}) error { 164 msg := fmt.Sprintf(format, args...) 165 return fmt.Errorf("%s%d,%s", errRPCCodedErrorPrefix, code, msg) 166 } 167 168 // CodeFromRPCCodedErr returns the code and message of error if it's an RPC error 169 // created through NewErrRPCCoded function. Returns `ok` false if error is not 170 // an rpc error 171 func CodeFromRPCCodedErr(err error) (code int, msg string, ok bool) { 172 if err == nil || !strings.HasPrefix(err.Error(), errRPCCodedErrorPrefix) { 173 return 0, "", false 174 } 175 176 headerLen := len(errRPCCodedErrorPrefix) 177 parts := strings.SplitN(err.Error()[headerLen:], ",", 2) 178 if len(parts) != 2 { 179 return 0, "", false 180 } 181 182 code, err = strconv.Atoi(parts[0]) 183 if err != nil { 184 return 0, "", false 185 } 186 187 return code, parts[1], true 188 }