status.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright 2015, 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "Firestore/core/src/util/status.h"
  17. #include <ostream>
  18. #include <utility>
  19. #include "Firestore/core/src/util/hard_assert.h"
  20. #include "Firestore/core/src/util/string_format.h"
  21. #include "absl/memory/memory.h"
  22. namespace firebase {
  23. namespace firestore {
  24. namespace util {
  25. Status::Status(Error code, std::string msg) {
  26. HARD_ASSERT(code != Error::kErrorOk);
  27. state_ = State::MakePtr(code, std::move(msg));
  28. }
  29. Status Status::FromCause(std::string message, const Status& cause) {
  30. if (cause.ok()) {
  31. return cause;
  32. }
  33. return Status(cause.code(), std::move(message)).CausedBy(cause);
  34. }
  35. void Status::Update(const Status& new_status) {
  36. if (ok()) {
  37. *this = new_status;
  38. }
  39. }
  40. Status& Status::CausedBy(const Status& cause) {
  41. if (cause.ok() || this == &cause || cause.IsMovedFrom()) {
  42. return *this;
  43. }
  44. if (ok() || IsMovedFrom()) {
  45. *this = cause;
  46. return *this;
  47. }
  48. std::string new_message = error_message();
  49. absl::StrAppend(&state_->msg, ": ", cause.error_message());
  50. // If this Status has no accompanying PlatformError but the cause does, create
  51. // a PlatformError for this Status ahead of time to preserve the causal chain
  52. // that Status doesn't otherwise support.
  53. if (state_->platform_error == nullptr &&
  54. cause.state_->platform_error != nullptr) {
  55. state_->platform_error =
  56. cause.state_->platform_error->WrapWith(code(), error_message());
  57. }
  58. return *this;
  59. }
  60. Status& Status::WithPlatformError(std::unique_ptr<PlatformError> error) {
  61. HARD_ASSERT(!ok(), "Platform errors should not be applied to Status::OK()");
  62. if (IsMovedFrom()) {
  63. std::string message = moved_from_message();
  64. state_ = State::MakePtr(Error::kErrorInternal, std::move(message));
  65. }
  66. state_->platform_error = std::move(error);
  67. return *this;
  68. }
  69. void Status::State::Deleter::operator()(const State* ptr) const {
  70. if (ptr != State::MovedFromIndicator()) {
  71. delete ptr;
  72. }
  73. }
  74. void Status::SetMovedFrom() {
  75. // Set pointer value to `0x1` as the pointer is no longer useful.
  76. state_ = State::StatePtr{State::MovedFromIndicator()};
  77. }
  78. void Status::SlowCopyFrom(const State* src) {
  79. if (src == nullptr) {
  80. state_ = nullptr;
  81. } else {
  82. state_ = State::MakePtr(*src);
  83. }
  84. }
  85. const std::string& Status::empty_string() {
  86. static std::string* empty = new std::string;
  87. return *empty;
  88. }
  89. const std::string& Status::moved_from_message() {
  90. static std::string* message = new std::string("Status accessed after move.");
  91. return *message;
  92. }
  93. std::string Status::ToString() const {
  94. if (state_ == nullptr) {
  95. return "OK";
  96. } else {
  97. std::string result;
  98. switch (code()) {
  99. case Error::kErrorCancelled:
  100. result = "Cancelled";
  101. break;
  102. case Error::kErrorUnknown:
  103. result = "Unknown";
  104. break;
  105. case Error::kErrorInvalidArgument:
  106. result = "Invalid argument";
  107. break;
  108. case Error::kErrorDeadlineExceeded:
  109. result = "Deadline exceeded";
  110. break;
  111. case Error::kErrorNotFound:
  112. result = "Not found";
  113. break;
  114. case Error::kErrorAlreadyExists:
  115. result = "Already exists";
  116. break;
  117. case Error::kErrorPermissionDenied:
  118. result = "Permission denied";
  119. break;
  120. case Error::kErrorUnauthenticated:
  121. result = "Unauthenticated";
  122. break;
  123. case Error::kErrorResourceExhausted:
  124. result = "Resource exhausted";
  125. break;
  126. case Error::kErrorFailedPrecondition:
  127. result = "Failed precondition";
  128. break;
  129. case Error::kErrorAborted:
  130. result = "Aborted";
  131. break;
  132. case Error::kErrorOutOfRange:
  133. result = "Out of range";
  134. break;
  135. case Error::kErrorUnimplemented:
  136. result = "Unimplemented";
  137. break;
  138. case Error::kErrorInternal:
  139. result = "Internal";
  140. break;
  141. case Error::kErrorUnavailable:
  142. result = "Unavailable";
  143. break;
  144. case Error::kErrorDataLoss:
  145. result = "Data loss";
  146. break;
  147. default:
  148. result = StringFormat("Unknown code(%s)", code());
  149. break;
  150. }
  151. result += ": ";
  152. result += IsMovedFrom() ? moved_from_message() : state_->msg;
  153. return result;
  154. }
  155. }
  156. std::ostream& operator<<(std::ostream& out, const Status& status) {
  157. out << status.ToString();
  158. return out;
  159. }
  160. void Status::IgnoreError() const {
  161. // no-op
  162. }
  163. std::string StatusCheckOpHelperOutOfLine(const Status& v, const char* msg) {
  164. HARD_ASSERT(!v.ok());
  165. std::string r("Non-OK-status: ");
  166. r += msg;
  167. r += " status: ";
  168. r += v.ToString();
  169. return r;
  170. }
  171. } // namespace util
  172. } // namespace firestore
  173. } // namespace firebase