|
| 1 | +package errors |
| 2 | + |
| 3 | +type ErrorCode uint32 |
| 4 | + |
| 5 | +// Capability error codes are primarily based on gRPC error codes: |
| 6 | +// https://grpc.github.io/grpc/core/md_doc_statuscodes.html |
| 7 | +// Custom error codes specific to this project should start from 100 to avoid |
| 8 | +// conflicts with future gRPC codes. Note: 0 (OK) is intentionally excluded |
| 9 | +// because capability errors must always indicate a failure condition. |
| 10 | +const ( |
| 11 | + // Canceled indicates the operation was canceled (typically by the caller). |
| 12 | + Canceled ErrorCode = 1 |
| 13 | + |
| 14 | + // Unknown error. An example of where this error may be returned is |
| 15 | + // if a Status value received from another address space belongs to |
| 16 | + // an error-space that is not known in this address space. Also |
| 17 | + // errors raised by APIs that do not return enough error information |
| 18 | + // may be converted to this error. |
| 19 | + Unknown ErrorCode = 2 |
| 20 | + |
| 21 | + // InvalidArgument indicates client specified an invalid argument. |
| 22 | + // Note that this differs from FailedPrecondition. It indicates arguments |
| 23 | + // that are problematic regardless of the state of the system |
| 24 | + // (e.g., a malformed file name). |
| 25 | + InvalidArgument ErrorCode = 3 |
| 26 | + |
| 27 | + // DeadlineExceeded means operation expired before completion. |
| 28 | + // For operations that change the state of the system, this error may be |
| 29 | + // returned even if the operation has completed successfully. For |
| 30 | + // example, a successful response from a server could have been delayed |
| 31 | + // long enough for the deadline to expire. |
| 32 | + DeadlineExceeded ErrorCode = 4 |
| 33 | + |
| 34 | + // NotFound means some requested entity (e.g., file or directory) was |
| 35 | + // not found. |
| 36 | + NotFound ErrorCode = 5 |
| 37 | + |
| 38 | + // AlreadyExists means an attempt to create an entity failed because one |
| 39 | + // already exists. |
| 40 | + AlreadyExists ErrorCode = 6 |
| 41 | + |
| 42 | + // PermissionDenied indicates the caller does not have permission to |
| 43 | + // execute the specified operation. It must not be used for rejections |
| 44 | + // caused by exhausting some resource (use ResourceExhausted |
| 45 | + // instead for those errors). It must not be |
| 46 | + // used if the caller cannot be identified (use Unauthenticated |
| 47 | + // instead for those errors). |
| 48 | + PermissionDenied ErrorCode = 7 |
| 49 | + |
| 50 | + // ResourceExhausted indicates some resource has been exhausted, perhaps |
| 51 | + // a per-user quota, or perhaps the entire file system is out of space. |
| 52 | + ResourceExhausted ErrorCode = 8 |
| 53 | + |
| 54 | + // FailedPrecondition indicates operation was rejected because the |
| 55 | + // system is not in a state required for the operation's execution. |
| 56 | + // For example, directory to be deleted may be non-empty, an rmdir |
| 57 | + // operation is applied to a non-directory, etc. |
| 58 | + // |
| 59 | + // A litmus test that may help a service implementor in deciding |
| 60 | + // between FailedPrecondition, Aborted, and Unavailable: |
| 61 | + // (a) Use Unavailable if the client can retry just the failing call. |
| 62 | + // (b) Use Aborted if the client should retry at a higher-level |
| 63 | + // (e.g., restarting a read-modify-write sequence). |
| 64 | + // (c) Use FailedPrecondition if the client should not retry until |
| 65 | + // the system state has been explicitly fixed. E.g., if an "rmdir" |
| 66 | + // fails because the directory is non-empty, FailedPrecondition |
| 67 | + // should be returned since the client should not retry unless |
| 68 | + // they have first fixed up the directory by deleting files from it. |
| 69 | + // (d) Use FailedPrecondition if the client performs conditional |
| 70 | + // REST Get/Update/Delete on a resource and the resource on the |
| 71 | + // server does not match the condition. E.g., conflicting |
| 72 | + // read-modify-write on the same resource. |
| 73 | + FailedPrecondition ErrorCode = 9 |
| 74 | + |
| 75 | + // Aborted indicates the operation was aborted, typically due to a |
| 76 | + // concurrency issue like sequencer check failures, transaction aborts, |
| 77 | + // etc. |
| 78 | + // |
| 79 | + // See litmus test above for deciding between FailedPrecondition, |
| 80 | + // Aborted, and Unavailable. |
| 81 | + Aborted ErrorCode = 10 |
| 82 | + |
| 83 | + // OutOfRange means operation was attempted past the valid range. |
| 84 | + // E.g., seeking or reading past end of file. |
| 85 | + // |
| 86 | + // Unlike InvalidArgument, this error indicates a problem that may |
| 87 | + // be fixed if the system state changes. For example, a 32-bit file |
| 88 | + // system will generate InvalidArgument if asked to read at an |
| 89 | + // offset that is not in the range [0,2^32-1], but it will generate |
| 90 | + // OutOfRange if asked to read from an offset past the current |
| 91 | + // file size. |
| 92 | + // |
| 93 | + // There is a fair bit of overlap between FailedPrecondition and |
| 94 | + // OutOfRange. We recommend using OutOfRange (the more specific |
| 95 | + // error) when it applies so that callers who are iterating through |
| 96 | + // a space can easily look for an OutOfRange error to detect when |
| 97 | + // they are done. |
| 98 | + OutOfRange ErrorCode = 11 |
| 99 | + |
| 100 | + // Unimplemented indicates operation is not implemented or not |
| 101 | + // supported/enabled in this service. |
| 102 | + Unimplemented ErrorCode = 12 |
| 103 | + |
| 104 | + // Internal errors. Means some invariants expected by underlying |
| 105 | + // system has been broken. If you see one of these errors, |
| 106 | + // something is very broken. |
| 107 | + Internal ErrorCode = 13 |
| 108 | + |
| 109 | + // Unavailable indicates the service is currently unavailable. |
| 110 | + // This is a most likely a transient condition and may be corrected |
| 111 | + // by retrying with a backoff. Note that it is not always safe to retry |
| 112 | + // non-idempotent operations. |
| 113 | + // |
| 114 | + // See litmus test above for deciding between FailedPrecondition, |
| 115 | + // Aborted, and Unavailable. |
| 116 | + Unavailable ErrorCode = 14 |
| 117 | + |
| 118 | + // DataLoss indicates unrecoverable data loss or corruption. |
| 119 | + DataLoss ErrorCode = 15 |
| 120 | + |
| 121 | + // Unauthenticated indicates the request does not have valid |
| 122 | + // authentication credentials for the operation. |
| 123 | + Unauthenticated ErrorCode = 16 |
| 124 | + |
| 125 | + // Custom error codes not defined in the gRPC error space are defined below this point, |
| 126 | + // starting at 100 to avoid collision with future gRPC defined codes. |
| 127 | + |
| 128 | + // ConsensusFailed indicates failure to reach consensus |
| 129 | + ConsensusFailed ErrorCode = 100 |
| 130 | +) |
| 131 | + |
| 132 | +// String returns the string representation of the ErrorCode. |
| 133 | +func (e ErrorCode) String() string { |
| 134 | + if s, ok := errorCodeToString[e]; ok { |
| 135 | + return s |
| 136 | + } |
| 137 | + return "Unknown" |
| 138 | +} |
| 139 | + |
| 140 | +var errorCodeToString = map[ErrorCode]string{ |
| 141 | + Canceled: "Canceled", |
| 142 | + Unknown: "Unknown", |
| 143 | + InvalidArgument: "InvalidArgument", |
| 144 | + DeadlineExceeded: "DeadlineExceeded", |
| 145 | + NotFound: "NotFound", |
| 146 | + AlreadyExists: "AlreadyExists", |
| 147 | + PermissionDenied: "PermissionDenied", |
| 148 | + ResourceExhausted: "ResourceExhausted", |
| 149 | + FailedPrecondition: "FailedPrecondition", |
| 150 | + Aborted: "Aborted", |
| 151 | + OutOfRange: "OutOfRange", |
| 152 | + Unimplemented: "Unimplemented", |
| 153 | + Internal: "Internal", |
| 154 | + Unavailable: "Unavailable", |
| 155 | + DataLoss: "DataLoss", |
| 156 | + Unauthenticated: "Unauthenticated", |
| 157 | + ConsensusFailed: "ConsensusFailed", |
| 158 | +} |
| 159 | + |
| 160 | +var stringToErrorCode = map[string]ErrorCode{ |
| 161 | + "Canceled": Canceled, |
| 162 | + "Unknown": Unknown, |
| 163 | + "InvalidArgument": InvalidArgument, |
| 164 | + "DeadlineExceeded": DeadlineExceeded, |
| 165 | + "NotFound": NotFound, |
| 166 | + "AlreadyExists": AlreadyExists, |
| 167 | + "PermissionDenied": PermissionDenied, |
| 168 | + "ResourceExhausted": ResourceExhausted, |
| 169 | + "FailedPrecondition": FailedPrecondition, |
| 170 | + "Aborted": Aborted, |
| 171 | + "OutOfRange": OutOfRange, |
| 172 | + "Unimplemented": Unimplemented, |
| 173 | + "Internal": Internal, |
| 174 | + "Unavailable": Unavailable, |
| 175 | + "DataLoss": DataLoss, |
| 176 | + "Unauthenticated": Unauthenticated, |
| 177 | + "ConsensusFailed": ConsensusFailed, |
| 178 | +} |
| 179 | + |
| 180 | +func FromErrorCodeString(str string) ErrorCode { |
| 181 | + if code, ok := stringToErrorCode[str]; ok { |
| 182 | + return code |
| 183 | + } |
| 184 | + return Unknown |
| 185 | +} |
0 commit comments