status.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. // Copyright 2019 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/status/status.h"
  15. #include <errno.h>
  16. #include <atomic>
  17. #include <cstddef>
  18. #include <cstdint>
  19. #include <cstring>
  20. #include <memory>
  21. #include <ostream>
  22. #include <string>
  23. #include "absl/base/attributes.h"
  24. #include "absl/base/config.h"
  25. #include "absl/base/internal/raw_logging.h"
  26. #include "absl/base/internal/strerror.h"
  27. #include "absl/base/macros.h"
  28. #include "absl/base/no_destructor.h"
  29. #include "absl/base/nullability.h"
  30. #include "absl/debugging/stacktrace.h"
  31. #include "absl/debugging/symbolize.h"
  32. #include "absl/status/internal/status_internal.h"
  33. #include "absl/strings/str_cat.h"
  34. #include "absl/strings/str_format.h"
  35. #include "absl/strings/str_split.h"
  36. #include "absl/strings/string_view.h"
  37. #include "absl/types/optional.h"
  38. namespace absl {
  39. ABSL_NAMESPACE_BEGIN
  40. static_assert(
  41. alignof(status_internal::StatusRep) >= 4,
  42. "absl::Status assumes it can use the bottom 2 bits of a StatusRep*.");
  43. std::string StatusCodeToString(StatusCode code) {
  44. switch (code) {
  45. case StatusCode::kOk:
  46. return "OK";
  47. case StatusCode::kCancelled:
  48. return "CANCELLED";
  49. case StatusCode::kUnknown:
  50. return "UNKNOWN";
  51. case StatusCode::kInvalidArgument:
  52. return "INVALID_ARGUMENT";
  53. case StatusCode::kDeadlineExceeded:
  54. return "DEADLINE_EXCEEDED";
  55. case StatusCode::kNotFound:
  56. return "NOT_FOUND";
  57. case StatusCode::kAlreadyExists:
  58. return "ALREADY_EXISTS";
  59. case StatusCode::kPermissionDenied:
  60. return "PERMISSION_DENIED";
  61. case StatusCode::kUnauthenticated:
  62. return "UNAUTHENTICATED";
  63. case StatusCode::kResourceExhausted:
  64. return "RESOURCE_EXHAUSTED";
  65. case StatusCode::kFailedPrecondition:
  66. return "FAILED_PRECONDITION";
  67. case StatusCode::kAborted:
  68. return "ABORTED";
  69. case StatusCode::kOutOfRange:
  70. return "OUT_OF_RANGE";
  71. case StatusCode::kUnimplemented:
  72. return "UNIMPLEMENTED";
  73. case StatusCode::kInternal:
  74. return "INTERNAL";
  75. case StatusCode::kUnavailable:
  76. return "UNAVAILABLE";
  77. case StatusCode::kDataLoss:
  78. return "DATA_LOSS";
  79. default:
  80. return "";
  81. }
  82. }
  83. std::ostream& operator<<(std::ostream& os, StatusCode code) {
  84. return os << StatusCodeToString(code);
  85. }
  86. absl::Nonnull<const std::string*> Status::EmptyString() {
  87. static const absl::NoDestructor<std::string> kEmpty;
  88. return kEmpty.get();
  89. }
  90. #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
  91. constexpr const char Status::kMovedFromString[];
  92. #endif
  93. absl::Nonnull<const std::string*> Status::MovedFromString() {
  94. static const absl::NoDestructor<std::string> kMovedFrom(kMovedFromString);
  95. return kMovedFrom.get();
  96. }
  97. Status::Status(absl::StatusCode code, absl::string_view msg)
  98. : rep_(CodeToInlinedRep(code)) {
  99. if (code != absl::StatusCode::kOk && !msg.empty()) {
  100. rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr));
  101. }
  102. }
  103. absl::Nonnull<status_internal::StatusRep*> Status::PrepareToModify(
  104. uintptr_t rep) {
  105. if (IsInlined(rep)) {
  106. return new status_internal::StatusRep(InlinedRepToCode(rep),
  107. absl::string_view(), nullptr);
  108. }
  109. return RepToPointer(rep)->CloneAndUnref();
  110. }
  111. std::string Status::ToStringSlow(uintptr_t rep, StatusToStringMode mode) {
  112. if (IsInlined(rep)) {
  113. return absl::StrCat(absl::StatusCodeToString(InlinedRepToCode(rep)), ": ");
  114. }
  115. return RepToPointer(rep)->ToString(mode);
  116. }
  117. std::ostream& operator<<(std::ostream& os, const Status& x) {
  118. os << x.ToString(StatusToStringMode::kWithEverything);
  119. return os;
  120. }
  121. Status AbortedError(absl::string_view message) {
  122. return Status(absl::StatusCode::kAborted, message);
  123. }
  124. Status AlreadyExistsError(absl::string_view message) {
  125. return Status(absl::StatusCode::kAlreadyExists, message);
  126. }
  127. Status CancelledError(absl::string_view message) {
  128. return Status(absl::StatusCode::kCancelled, message);
  129. }
  130. Status DataLossError(absl::string_view message) {
  131. return Status(absl::StatusCode::kDataLoss, message);
  132. }
  133. Status DeadlineExceededError(absl::string_view message) {
  134. return Status(absl::StatusCode::kDeadlineExceeded, message);
  135. }
  136. Status FailedPreconditionError(absl::string_view message) {
  137. return Status(absl::StatusCode::kFailedPrecondition, message);
  138. }
  139. Status InternalError(absl::string_view message) {
  140. return Status(absl::StatusCode::kInternal, message);
  141. }
  142. Status InvalidArgumentError(absl::string_view message) {
  143. return Status(absl::StatusCode::kInvalidArgument, message);
  144. }
  145. Status NotFoundError(absl::string_view message) {
  146. return Status(absl::StatusCode::kNotFound, message);
  147. }
  148. Status OutOfRangeError(absl::string_view message) {
  149. return Status(absl::StatusCode::kOutOfRange, message);
  150. }
  151. Status PermissionDeniedError(absl::string_view message) {
  152. return Status(absl::StatusCode::kPermissionDenied, message);
  153. }
  154. Status ResourceExhaustedError(absl::string_view message) {
  155. return Status(absl::StatusCode::kResourceExhausted, message);
  156. }
  157. Status UnauthenticatedError(absl::string_view message) {
  158. return Status(absl::StatusCode::kUnauthenticated, message);
  159. }
  160. Status UnavailableError(absl::string_view message) {
  161. return Status(absl::StatusCode::kUnavailable, message);
  162. }
  163. Status UnimplementedError(absl::string_view message) {
  164. return Status(absl::StatusCode::kUnimplemented, message);
  165. }
  166. Status UnknownError(absl::string_view message) {
  167. return Status(absl::StatusCode::kUnknown, message);
  168. }
  169. bool IsAborted(const Status& status) {
  170. return status.code() == absl::StatusCode::kAborted;
  171. }
  172. bool IsAlreadyExists(const Status& status) {
  173. return status.code() == absl::StatusCode::kAlreadyExists;
  174. }
  175. bool IsCancelled(const Status& status) {
  176. return status.code() == absl::StatusCode::kCancelled;
  177. }
  178. bool IsDataLoss(const Status& status) {
  179. return status.code() == absl::StatusCode::kDataLoss;
  180. }
  181. bool IsDeadlineExceeded(const Status& status) {
  182. return status.code() == absl::StatusCode::kDeadlineExceeded;
  183. }
  184. bool IsFailedPrecondition(const Status& status) {
  185. return status.code() == absl::StatusCode::kFailedPrecondition;
  186. }
  187. bool IsInternal(const Status& status) {
  188. return status.code() == absl::StatusCode::kInternal;
  189. }
  190. bool IsInvalidArgument(const Status& status) {
  191. return status.code() == absl::StatusCode::kInvalidArgument;
  192. }
  193. bool IsNotFound(const Status& status) {
  194. return status.code() == absl::StatusCode::kNotFound;
  195. }
  196. bool IsOutOfRange(const Status& status) {
  197. return status.code() == absl::StatusCode::kOutOfRange;
  198. }
  199. bool IsPermissionDenied(const Status& status) {
  200. return status.code() == absl::StatusCode::kPermissionDenied;
  201. }
  202. bool IsResourceExhausted(const Status& status) {
  203. return status.code() == absl::StatusCode::kResourceExhausted;
  204. }
  205. bool IsUnauthenticated(const Status& status) {
  206. return status.code() == absl::StatusCode::kUnauthenticated;
  207. }
  208. bool IsUnavailable(const Status& status) {
  209. return status.code() == absl::StatusCode::kUnavailable;
  210. }
  211. bool IsUnimplemented(const Status& status) {
  212. return status.code() == absl::StatusCode::kUnimplemented;
  213. }
  214. bool IsUnknown(const Status& status) {
  215. return status.code() == absl::StatusCode::kUnknown;
  216. }
  217. StatusCode ErrnoToStatusCode(int error_number) {
  218. switch (error_number) {
  219. case 0:
  220. return StatusCode::kOk;
  221. case EINVAL: // Invalid argument
  222. case ENAMETOOLONG: // Filename too long
  223. case E2BIG: // Argument list too long
  224. case EDESTADDRREQ: // Destination address required
  225. case EDOM: // Mathematics argument out of domain of function
  226. case EFAULT: // Bad address
  227. case EILSEQ: // Illegal byte sequence
  228. case ENOPROTOOPT: // Protocol not available
  229. case ENOTSOCK: // Not a socket
  230. case ENOTTY: // Inappropriate I/O control operation
  231. case EPROTOTYPE: // Protocol wrong type for socket
  232. case ESPIPE: // Invalid seek
  233. return StatusCode::kInvalidArgument;
  234. case ETIMEDOUT: // Connection timed out
  235. return StatusCode::kDeadlineExceeded;
  236. case ENODEV: // No such device
  237. case ENOENT: // No such file or directory
  238. #ifdef ENOMEDIUM
  239. case ENOMEDIUM: // No medium found
  240. #endif
  241. case ENXIO: // No such device or address
  242. case ESRCH: // No such process
  243. return StatusCode::kNotFound;
  244. case EEXIST: // File exists
  245. case EADDRNOTAVAIL: // Address not available
  246. case EALREADY: // Connection already in progress
  247. #ifdef ENOTUNIQ
  248. case ENOTUNIQ: // Name not unique on network
  249. #endif
  250. return StatusCode::kAlreadyExists;
  251. case EPERM: // Operation not permitted
  252. case EACCES: // Permission denied
  253. #ifdef ENOKEY
  254. case ENOKEY: // Required key not available
  255. #endif
  256. case EROFS: // Read only file system
  257. return StatusCode::kPermissionDenied;
  258. case ENOTEMPTY: // Directory not empty
  259. case EISDIR: // Is a directory
  260. case ENOTDIR: // Not a directory
  261. case EADDRINUSE: // Address already in use
  262. case EBADF: // Invalid file descriptor
  263. #ifdef EBADFD
  264. case EBADFD: // File descriptor in bad state
  265. #endif
  266. case EBUSY: // Device or resource busy
  267. case ECHILD: // No child processes
  268. case EISCONN: // Socket is connected
  269. #ifdef EISNAM
  270. case EISNAM: // Is a named type file
  271. #endif
  272. #ifdef ENOTBLK
  273. case ENOTBLK: // Block device required
  274. #endif
  275. case ENOTCONN: // The socket is not connected
  276. case EPIPE: // Broken pipe
  277. #ifdef ESHUTDOWN
  278. case ESHUTDOWN: // Cannot send after transport endpoint shutdown
  279. #endif
  280. case ETXTBSY: // Text file busy
  281. #ifdef EUNATCH
  282. case EUNATCH: // Protocol driver not attached
  283. #endif
  284. return StatusCode::kFailedPrecondition;
  285. case ENOSPC: // No space left on device
  286. #ifdef EDQUOT
  287. case EDQUOT: // Disk quota exceeded
  288. #endif
  289. case EMFILE: // Too many open files
  290. case EMLINK: // Too many links
  291. case ENFILE: // Too many open files in system
  292. case ENOBUFS: // No buffer space available
  293. case ENOMEM: // Not enough space
  294. #ifdef EUSERS
  295. case EUSERS: // Too many users
  296. #endif
  297. return StatusCode::kResourceExhausted;
  298. #ifdef ECHRNG
  299. case ECHRNG: // Channel number out of range
  300. #endif
  301. case EFBIG: // File too large
  302. case EOVERFLOW: // Value too large to be stored in data type
  303. case ERANGE: // Result too large
  304. return StatusCode::kOutOfRange;
  305. #ifdef ENOPKG
  306. case ENOPKG: // Package not installed
  307. #endif
  308. case ENOSYS: // Function not implemented
  309. case ENOTSUP: // Operation not supported
  310. case EAFNOSUPPORT: // Address family not supported
  311. #ifdef EPFNOSUPPORT
  312. case EPFNOSUPPORT: // Protocol family not supported
  313. #endif
  314. case EPROTONOSUPPORT: // Protocol not supported
  315. #ifdef ESOCKTNOSUPPORT
  316. case ESOCKTNOSUPPORT: // Socket type not supported
  317. #endif
  318. case EXDEV: // Improper link
  319. return StatusCode::kUnimplemented;
  320. case EAGAIN: // Resource temporarily unavailable
  321. #ifdef ECOMM
  322. case ECOMM: // Communication error on send
  323. #endif
  324. case ECONNREFUSED: // Connection refused
  325. case ECONNABORTED: // Connection aborted
  326. case ECONNRESET: // Connection reset
  327. case EINTR: // Interrupted function call
  328. #ifdef EHOSTDOWN
  329. case EHOSTDOWN: // Host is down
  330. #endif
  331. case EHOSTUNREACH: // Host is unreachable
  332. case ENETDOWN: // Network is down
  333. case ENETRESET: // Connection aborted by network
  334. case ENETUNREACH: // Network unreachable
  335. case ENOLCK: // No locks available
  336. case ENOLINK: // Link has been severed
  337. #ifdef ENONET
  338. case ENONET: // Machine is not on the network
  339. #endif
  340. return StatusCode::kUnavailable;
  341. case EDEADLK: // Resource deadlock avoided
  342. #ifdef ESTALE
  343. case ESTALE: // Stale file handle
  344. #endif
  345. return StatusCode::kAborted;
  346. case ECANCELED: // Operation cancelled
  347. return StatusCode::kCancelled;
  348. default:
  349. return StatusCode::kUnknown;
  350. }
  351. }
  352. namespace {
  353. std::string MessageForErrnoToStatus(int error_number,
  354. absl::string_view message) {
  355. return absl::StrCat(message, ": ",
  356. absl::base_internal::StrError(error_number));
  357. }
  358. } // namespace
  359. Status ErrnoToStatus(int error_number, absl::string_view message) {
  360. return Status(ErrnoToStatusCode(error_number),
  361. MessageForErrnoToStatus(error_number, message));
  362. }
  363. absl::Nonnull<const char*> StatusMessageAsCStr(const Status& status) {
  364. // As an internal implementation detail, we guarantee that if status.message()
  365. // is non-empty, then the resulting string_view is null terminated.
  366. auto sv_message = status.message();
  367. return sv_message.empty() ? "" : sv_message.data();
  368. }
  369. ABSL_NAMESPACE_END
  370. } // namespace absl