go.uber.org/yarpc@v1.72.1/yarpcerrors/codes.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package yarpcerrors 22 23 import ( 24 "fmt" 25 "strconv" 26 "strings" 27 ) 28 29 const ( 30 // CodeOK means no error; returned on success 31 CodeOK Code = 0 32 33 // CodeCancelled means the operation was cancelled, typically by the caller. 34 // This is considered as a client error. 35 CodeCancelled Code = 1 36 37 // CodeUnknown means an unknown error. Errors raised by APIs 38 // that do not return enough error information 39 // may be converted to this error. 40 // This is considered as a server error. 41 CodeUnknown Code = 2 42 43 // CodeInvalidArgument means the client specified an invalid argument. 44 // Note that this differs from `FailedPrecondition`. `InvalidArgument` 45 // indicates arguments that are problematic regardless of the state of 46 // the system (e.g., a malformed file name). 47 // This is considered as a client error. 48 CodeInvalidArgument Code = 3 49 50 // CodeDeadlineExceeded means the deadline expired before the operation could 51 // complete. For operations that change the state of the system, this error 52 // may be returned even if the operation has completed successfully. For example, 53 // a successful response from a server could have been delayed long 54 // enough for the deadline to expire. 55 // This is considered as a server error. 56 CodeDeadlineExceeded Code = 4 57 58 // CodeNotFound means some requested entity (e.g., file or directory) was not found. 59 // For privacy reasons, this code *may* be returned when the client 60 // does not have the access rights to the entity, though such usage is 61 // discouraged. 62 // This is considered as a client error. 63 CodeNotFound Code = 5 64 65 // CodeAlreadyExists means the entity that a client attempted to create 66 // (e.g., file or directory) already exists. 67 // This is considered as a client error. 68 CodeAlreadyExists Code = 6 69 70 // CodePermissionDenied means the caller does not have permission to execute 71 // the specified operation. `PermissionDenied` must not be used for rejections 72 // caused by exhausting some resource (use `ResourceExhausted` 73 // instead for those errors). `PermissionDenied` must not be 74 // used if the caller can not be identified (use `Unauthenticated` 75 // instead for those errors). 76 // This is considered as a client error. 77 CodePermissionDenied Code = 7 78 79 // CodeResourceExhausted means some resource has been exhausted, perhaps a per-user 80 // quota, or perhaps the entire file system is out of space. 81 // This is considered as a client error. 82 CodeResourceExhausted Code = 8 83 84 // CodeFailedPrecondition means the operation was rejected because the system is not 85 // in a state required for the operation's execution. For example, the directory 86 // to be deleted is non-empty, an rmdir operation is applied to 87 // a non-directory, etc. 88 // 89 // Service implementors can use the following guidelines to decide 90 // between `FailedPrecondition`, `Aborted`, and `Unavailable`: 91 // (a) Use `Unavailable` if the client can retry just the failing call. 92 // (b) Use `Aborted` if the client should retry at a higher level 93 // (e.g., restarting a read-modify-write sequence). 94 // (c) Use `FailedPrecondition` if the client should not retry until 95 // the system state has been explicitly fixed. E.g., if an "rmdir" 96 // fails because the directory is non-empty, `FailedPrecondition` 97 // should be returned since the client should not retry unless 98 // the files are deleted from the directory. 99 // This is considered as a client error. 100 CodeFailedPrecondition Code = 9 101 102 // CodeAborted means the operation was aborted, typically due to a concurrency issue 103 // such as a sequencer check failure or transaction abort. 104 // 105 // See the guidelines above for deciding between `FailedPrecondition`, 106 // `Aborted`, and `Unavailable`. 107 // This is considered as a client error. 108 CodeAborted Code = 10 109 110 // CodeOutOfRange means the operation was attempted past the valid range. 111 // E.g., seeking or reading past end-of-file. 112 // 113 // Unlike `InvalidArgument`, this error indicates a problem that may 114 // be fixed if the system state changes. For example, a 32-bit file 115 // system will generate `InvalidArgument` if asked to read at an 116 // offset that is not in the range [0,2^32-1], but it will generate 117 // `OutOfRange` if asked to read from an offset past the current 118 // file size. 119 // 120 // There is a fair bit of overlap between `FailedPrecondition` and 121 // `OutOfRange`. We recommend using `OutOfRange` (the more specific 122 // error) when it applies so that callers who are iterating through 123 // a space can easily look for an `OutOfRange` error to detect when 124 // they are done. 125 // This is considered as a client error. 126 CodeOutOfRange Code = 11 127 128 // CodeUnimplemented means the operation is not implemented or is not 129 // supported/enabled in this service. 130 // This is considered as a client error. 131 CodeUnimplemented Code = 12 132 133 // CodeInternal means an internal error. This means that some invariants expected 134 // by the underlying system have been broken. This error code is reserved 135 // for serious errors. 136 // This is considered as a server error. 137 CodeInternal Code = 13 138 139 // CodeUnavailable means the service is currently unavailable. This is most likely a 140 // transient condition, which can be corrected by retrying with a backoff. 141 // 142 // See the guidelines above for deciding between `FailedPrecondition`, 143 // `Aborted`, and `Unavailable`. 144 // This is considered as a server error. 145 CodeUnavailable Code = 14 146 147 // CodeDataLoss means unrecoverable data loss or corruption. 148 // This is considered as a server error. 149 CodeDataLoss Code = 15 150 151 // CodeUnauthenticated means the request does not have valid authentication 152 // credentials for the operation. 153 // This is considered as a client error. 154 CodeUnauthenticated Code = 16 155 ) 156 157 var ( 158 _codeToString = map[Code]string{ 159 CodeOK: "ok", 160 CodeCancelled: "cancelled", 161 CodeUnknown: "unknown", 162 CodeInvalidArgument: "invalid-argument", 163 CodeDeadlineExceeded: "deadline-exceeded", 164 CodeNotFound: "not-found", 165 CodeAlreadyExists: "already-exists", 166 CodePermissionDenied: "permission-denied", 167 CodeResourceExhausted: "resource-exhausted", 168 CodeFailedPrecondition: "failed-precondition", 169 CodeAborted: "aborted", 170 CodeOutOfRange: "out-of-range", 171 CodeUnimplemented: "unimplemented", 172 CodeInternal: "internal", 173 CodeUnavailable: "unavailable", 174 CodeDataLoss: "data-loss", 175 CodeUnauthenticated: "unauthenticated", 176 } 177 _stringToCode = map[string]Code{ 178 "ok": CodeOK, 179 "cancelled": CodeCancelled, 180 "unknown": CodeUnknown, 181 "invalid-argument": CodeInvalidArgument, 182 "deadline-exceeded": CodeDeadlineExceeded, 183 "not-found": CodeNotFound, 184 "already-exists": CodeAlreadyExists, 185 "permission-denied": CodePermissionDenied, 186 "resource-exhausted": CodeResourceExhausted, 187 "failed-precondition": CodeFailedPrecondition, 188 "aborted": CodeAborted, 189 "out-of-range": CodeOutOfRange, 190 "unimplemented": CodeUnimplemented, 191 "internal": CodeInternal, 192 "unavailable": CodeUnavailable, 193 "data-loss": CodeDataLoss, 194 "unauthenticated": CodeUnauthenticated, 195 } 196 ) 197 198 // Code represents the type of error for an RPC call. 199 // 200 // Sometimes multiple error codes may apply. Services should return 201 // the most specific error code that applies. For example, prefer 202 // `OutOfRange` over `FailedPrecondition` if both codes apply. 203 // Similarly prefer `NotFound` or `AlreadyExists` over `FailedPrecondition`. 204 // 205 // These codes are meant to match gRPC status codes. 206 // https://godoc.org/google.golang.org/grpc/codes#Code 207 type Code int 208 209 // String returns the the string representation of the Code. 210 func (c Code) String() string { 211 s, ok := _codeToString[c] 212 if ok { 213 return s 214 } 215 return strconv.Itoa(int(c)) 216 } 217 218 // MarshalText implements encoding.TextMarshaler. 219 func (c Code) MarshalText() ([]byte, error) { 220 s, ok := _codeToString[c] 221 if ok { 222 return []byte(s), nil 223 } 224 return nil, fmt.Errorf("unknown code: %d", int(c)) 225 } 226 227 // UnmarshalText implements encoding.TextUnmarshaler. 228 func (c *Code) UnmarshalText(text []byte) error { 229 i, ok := _stringToCode[strings.ToLower(string(text))] 230 if !ok { 231 return fmt.Errorf("unknown code string: %s", string(text)) 232 } 233 *c = i 234 return nil 235 } 236 237 // MarshalJSON implements json.Marshaler. 238 func (c Code) MarshalJSON() ([]byte, error) { 239 s, ok := _codeToString[c] 240 if ok { 241 return []byte(`"` + s + `"`), nil 242 } 243 return nil, fmt.Errorf("unknown code: %d", int(c)) 244 } 245 246 // UnmarshalJSON implements json.Unmarshaler. 247 func (c *Code) UnmarshalJSON(text []byte) error { 248 s := string(text) 249 if len(s) < 3 || s[0] != '"' || s[len(s)-1] != '"' { 250 return fmt.Errorf("invalid code string: %s", s) 251 } 252 i, ok := _stringToCode[strings.ToLower(s[1:len(s)-1])] 253 if !ok { 254 return fmt.Errorf("unknown code string: %s", s) 255 } 256 *c = i 257 return nil 258 }